]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
devlink: Allocate devlink directly in requested net namespace
authorLeon Romanovsky <leonro@nvidia.com>
Thu, 29 Jul 2021 17:19:25 +0000 (20:19 +0300)
committerJakub Kicinski <kuba@kernel.org>
Fri, 30 Jul 2021 20:16:38 +0000 (13:16 -0700)
There is no need in extra call indirection and check from impossible
flow where someone tries to set namespace without prior call
to devlink_alloc().

Instead of this extra logic and additional EXPORT_SYMBOL, use specialized
devlink allocation function that receives net namespace as an argument.

Such specialized API allows clear view when devlink initialized in wrong
net namespace and/or kernel users don't try to change devlink namespace
under the hood.

Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/netdevsim/dev.c
include/net/devlink.h
net/core/devlink.c

index 6348307bfa849286df0cfbc3e8861438305829db..d538a39d42255b1c7dbd7eeb220c86845d085272 100644 (file)
@@ -1431,10 +1431,10 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
        struct devlink *devlink;
        int err;
 
-       devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev));
+       devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev),
+                                  nsim_bus_dev->initial_net);
        if (!devlink)
                return -ENOMEM;
-       devlink_net_set(devlink, nsim_bus_dev->initial_net);
        nsim_dev = devlink_priv(devlink);
        nsim_dev->nsim_bus_dev = nsim_bus_dev;
        nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
index e48a623204079cfa9b0c8fac9b73959976e3913c..08f4c6191e7299cda498fae85f97a01f479c9eda 100644 (file)
@@ -1540,8 +1540,18 @@ static inline struct devlink *netdev_to_devlink(struct net_device *dev)
 struct ib_device;
 
 struct net *devlink_net(const struct devlink *devlink);
-void devlink_net_set(struct devlink *devlink, struct net *net);
-struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size);
+/* This call is intended for software devices that can create
+ * devlink instances in other namespaces than init_net.
+ *
+ * Drivers that operate on real HW must use devlink_alloc() instead.
+ */
+struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
+                                size_t priv_size, struct net *net);
+static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
+                                           size_t priv_size)
+{
+       return devlink_alloc_ns(ops, priv_size, &init_net);
+}
 int devlink_register(struct devlink *devlink, struct device *dev);
 void devlink_unregister(struct devlink *devlink);
 void devlink_reload_enable(struct devlink *devlink);
index fbca61ad9bbc9a339e6e38c4fa59c735d7d997ca..fd2fc2befba922ab953d334cc6878d24fd29ccf6 100644 (file)
@@ -108,19 +108,6 @@ struct net *devlink_net(const struct devlink *devlink)
 }
 EXPORT_SYMBOL_GPL(devlink_net);
 
-static void __devlink_net_set(struct devlink *devlink, struct net *net)
-{
-       write_pnet(&devlink->_net, net);
-}
-
-void devlink_net_set(struct devlink *devlink, struct net *net)
-{
-       if (WARN_ON(devlink->dev))
-               return;
-       __devlink_net_set(devlink, net);
-}
-EXPORT_SYMBOL_GPL(devlink_net_set);
-
 static struct devlink *devlink_get_from_attrs(struct net *net,
                                              struct nlattr **attrs)
 {
@@ -3921,7 +3908,7 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
                return err;
 
        if (dest_net && !net_eq(dest_net, curr_net))
-               __devlink_net_set(devlink, dest_net);
+               write_pnet(&devlink->_net, dest_net);
 
        err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
        devlink_reload_failed_set(devlink, !!err);
@@ -8776,15 +8763,18 @@ static bool devlink_reload_actions_valid(const struct devlink_ops *ops)
 }
 
 /**
- *     devlink_alloc - Allocate new devlink instance resources
+ *     devlink_alloc_ns - Allocate new devlink instance resources
+ *     in specific namespace
  *
  *     @ops: ops
  *     @priv_size: size of user private data
+ *     @net: net namespace
  *
  *     Allocate new devlink instance resources, including devlink index
  *     and name.
  */
-struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
+struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
+                                size_t priv_size, struct net *net)
 {
        struct devlink *devlink;
 
@@ -8799,7 +8789,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
                return NULL;
        devlink->ops = ops;
        xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
-       __devlink_net_set(devlink, &init_net);
+       write_pnet(&devlink->_net, net);
        INIT_LIST_HEAD(&devlink->port_list);
        INIT_LIST_HEAD(&devlink->rate_list);
        INIT_LIST_HEAD(&devlink->sb_list);
@@ -8815,7 +8805,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
        mutex_init(&devlink->reporters_lock);
        return devlink;
 }
-EXPORT_SYMBOL_GPL(devlink_alloc);
+EXPORT_SYMBOL_GPL(devlink_alloc_ns);
 
 /**
  *     devlink_register - Register devlink instance