Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'clean-devlink-net-namespace-operations'

Leon Romanovsky says:

====================
Clean devlink net namespace operations

This short series continues my work on devlink core code to make devlink
reload less prone to errors and harden it from API abuse.

Despite first patch being a clear fix, I would ask you to apply it to
net-next anyway, because the fixed patch is anyway old and it will
help us to eliminate merge conflicts that will arise for following
patches or even for the second one.
====================

Link: https://lore.kernel.org/r/cover.1627578998.git.leonro@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+41 -33
+2 -2
drivers/net/netdevsim/dev.c
··· 1431 1431 struct devlink *devlink; 1432 1432 int err; 1433 1433 1434 - devlink = devlink_alloc(&nsim_dev_devlink_ops, sizeof(*nsim_dev)); 1434 + devlink = devlink_alloc_ns(&nsim_dev_devlink_ops, sizeof(*nsim_dev), 1435 + nsim_bus_dev->initial_net); 1435 1436 if (!devlink) 1436 1437 return -ENOMEM; 1437 - devlink_net_set(devlink, nsim_bus_dev->initial_net); 1438 1438 nsim_dev = devlink_priv(devlink); 1439 1439 nsim_dev->nsim_bus_dev = nsim_bus_dev; 1440 1440 nsim_dev->switch_id.id_len = sizeof(nsim_dev->switch_id.id);
+12 -2
include/net/devlink.h
··· 1540 1540 struct ib_device; 1541 1541 1542 1542 struct net *devlink_net(const struct devlink *devlink); 1543 - void devlink_net_set(struct devlink *devlink, struct net *net); 1544 - struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size); 1543 + /* This call is intended for software devices that can create 1544 + * devlink instances in other namespaces than init_net. 1545 + * 1546 + * Drivers that operate on real HW must use devlink_alloc() instead. 1547 + */ 1548 + struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, 1549 + size_t priv_size, struct net *net); 1550 + static inline struct devlink *devlink_alloc(const struct devlink_ops *ops, 1551 + size_t priv_size) 1552 + { 1553 + return devlink_alloc_ns(ops, priv_size, &init_net); 1554 + } 1545 1555 int devlink_register(struct devlink *devlink, struct device *dev); 1546 1556 void devlink_unregister(struct devlink *devlink); 1547 1557 void devlink_reload_enable(struct devlink *devlink);
+27 -29
net/core/devlink.c
··· 108 108 } 109 109 EXPORT_SYMBOL_GPL(devlink_net); 110 110 111 - static void __devlink_net_set(struct devlink *devlink, struct net *net) 112 - { 113 - write_pnet(&devlink->_net, net); 114 - } 115 - 116 - void devlink_net_set(struct devlink *devlink, struct net *net) 117 - { 118 - if (WARN_ON(devlink->dev)) 119 - return; 120 - __devlink_net_set(devlink, net); 121 - } 122 - EXPORT_SYMBOL_GPL(devlink_net_set); 123 - 124 111 static struct devlink *devlink_get_from_attrs(struct net *net, 125 112 struct nlattr **attrs) 126 113 { ··· 3788 3801 struct devlink_param_item *param_item, 3789 3802 enum devlink_command cmd); 3790 3803 3791 - static void devlink_reload_netns_change(struct devlink *devlink, 3792 - struct net *dest_net) 3804 + static void devlink_ns_change_notify(struct devlink *devlink, 3805 + struct net *dest_net, struct net *curr_net, 3806 + bool new) 3793 3807 { 3794 3808 struct devlink_param_item *param_item; 3809 + enum devlink_command cmd; 3795 3810 3796 3811 /* Userspace needs to be notified about devlink objects 3797 3812 * removed from original and entering new network namespace. ··· 3801 3812 * reload process so the notifications are generated separatelly. 3802 3813 */ 3803 3814 3804 - list_for_each_entry(param_item, &devlink->param_list, list) 3805 - devlink_param_notify(devlink, 0, param_item, 3806 - DEVLINK_CMD_PARAM_DEL); 3807 - devlink_notify(devlink, DEVLINK_CMD_DEL); 3815 + if (!dest_net || net_eq(dest_net, curr_net)) 3816 + return; 3808 3817 3809 - __devlink_net_set(devlink, dest_net); 3818 + if (new) 3819 + devlink_notify(devlink, DEVLINK_CMD_NEW); 3810 3820 3811 - devlink_notify(devlink, DEVLINK_CMD_NEW); 3821 + cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL; 3812 3822 list_for_each_entry(param_item, &devlink->param_list, list) 3813 - devlink_param_notify(devlink, 0, param_item, 3814 - DEVLINK_CMD_PARAM_NEW); 3823 + devlink_param_notify(devlink, 0, param_item, cmd); 3824 + 3825 + if (!new) 3826 + devlink_notify(devlink, DEVLINK_CMD_DEL); 3815 3827 } 3816 3828 3817 3829 static bool devlink_reload_supported(const struct devlink_ops *ops) ··· 3892 3902 u32 *actions_performed, struct netlink_ext_ack *extack) 3893 3903 { 3894 3904 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE]; 3905 + struct net *curr_net; 3895 3906 int err; 3896 3907 3897 3908 if (!devlink->reload_enabled) ··· 3900 3909 3901 3910 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats, 3902 3911 sizeof(remote_reload_stats)); 3912 + 3913 + curr_net = devlink_net(devlink); 3914 + devlink_ns_change_notify(devlink, dest_net, curr_net, false); 3903 3915 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack); 3904 3916 if (err) 3905 3917 return err; 3906 3918 3907 - if (dest_net && !net_eq(dest_net, devlink_net(devlink))) 3908 - devlink_reload_netns_change(devlink, dest_net); 3919 + if (dest_net && !net_eq(dest_net, curr_net)) 3920 + write_pnet(&devlink->_net, dest_net); 3909 3921 3910 3922 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack); 3911 3923 devlink_reload_failed_set(devlink, !!err); 3912 3924 if (err) 3913 3925 return err; 3914 3926 3927 + devlink_ns_change_notify(devlink, dest_net, curr_net, true); 3915 3928 WARN_ON(!(*actions_performed & BIT(action))); 3916 3929 /* Catch driver on updating the remote action within devlink reload */ 3917 3930 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats, ··· 8763 8768 } 8764 8769 8765 8770 /** 8766 - * devlink_alloc - Allocate new devlink instance resources 8771 + * devlink_alloc_ns - Allocate new devlink instance resources 8772 + * in specific namespace 8767 8773 * 8768 8774 * @ops: ops 8769 8775 * @priv_size: size of user private data 8776 + * @net: net namespace 8770 8777 * 8771 8778 * Allocate new devlink instance resources, including devlink index 8772 8779 * and name. 8773 8780 */ 8774 - struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) 8781 + struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, 8782 + size_t priv_size, struct net *net) 8775 8783 { 8776 8784 struct devlink *devlink; 8777 8785 ··· 8789 8791 return NULL; 8790 8792 devlink->ops = ops; 8791 8793 xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC); 8792 - __devlink_net_set(devlink, &init_net); 8794 + write_pnet(&devlink->_net, net); 8793 8795 INIT_LIST_HEAD(&devlink->port_list); 8794 8796 INIT_LIST_HEAD(&devlink->rate_list); 8795 8797 INIT_LIST_HEAD(&devlink->sb_list); ··· 8805 8807 mutex_init(&devlink->reporters_lock); 8806 8808 return devlink; 8807 8809 } 8808 - EXPORT_SYMBOL_GPL(devlink_alloc); 8810 + EXPORT_SYMBOL_GPL(devlink_alloc_ns); 8809 8811 8810 8812 /** 8811 8813 * devlink_register - Register devlink instance