mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-29 15:43:59 +08:00
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>
This commit is contained in:
commit
aae950b189
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
@ -3801,10 +3788,12 @@ static void devlink_param_notify(struct devlink *devlink,
|
||||
struct devlink_param_item *param_item,
|
||||
enum devlink_command cmd);
|
||||
|
||||
static void devlink_reload_netns_change(struct devlink *devlink,
|
||||
struct net *dest_net)
|
||||
static void devlink_ns_change_notify(struct devlink *devlink,
|
||||
struct net *dest_net, struct net *curr_net,
|
||||
bool new)
|
||||
{
|
||||
struct devlink_param_item *param_item;
|
||||
enum devlink_command cmd;
|
||||
|
||||
/* Userspace needs to be notified about devlink objects
|
||||
* removed from original and entering new network namespace.
|
||||
@ -3812,17 +3801,18 @@ static void devlink_reload_netns_change(struct devlink *devlink,
|
||||
* reload process so the notifications are generated separatelly.
|
||||
*/
|
||||
|
||||
list_for_each_entry(param_item, &devlink->param_list, list)
|
||||
devlink_param_notify(devlink, 0, param_item,
|
||||
DEVLINK_CMD_PARAM_DEL);
|
||||
devlink_notify(devlink, DEVLINK_CMD_DEL);
|
||||
if (!dest_net || net_eq(dest_net, curr_net))
|
||||
return;
|
||||
|
||||
__devlink_net_set(devlink, dest_net);
|
||||
if (new)
|
||||
devlink_notify(devlink, DEVLINK_CMD_NEW);
|
||||
|
||||
devlink_notify(devlink, DEVLINK_CMD_NEW);
|
||||
cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
|
||||
list_for_each_entry(param_item, &devlink->param_list, list)
|
||||
devlink_param_notify(devlink, 0, param_item,
|
||||
DEVLINK_CMD_PARAM_NEW);
|
||||
devlink_param_notify(devlink, 0, param_item, cmd);
|
||||
|
||||
if (!new)
|
||||
devlink_notify(devlink, DEVLINK_CMD_DEL);
|
||||
}
|
||||
|
||||
static bool devlink_reload_supported(const struct devlink_ops *ops)
|
||||
@ -3902,6 +3892,7 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
|
||||
u32 *actions_performed, struct netlink_ext_ack *extack)
|
||||
{
|
||||
u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
|
||||
struct net *curr_net;
|
||||
int err;
|
||||
|
||||
if (!devlink->reload_enabled)
|
||||
@ -3909,18 +3900,22 @@ static int devlink_reload(struct devlink *devlink, struct net *dest_net,
|
||||
|
||||
memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
|
||||
sizeof(remote_reload_stats));
|
||||
|
||||
curr_net = devlink_net(devlink);
|
||||
devlink_ns_change_notify(devlink, dest_net, curr_net, false);
|
||||
err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (dest_net && !net_eq(dest_net, devlink_net(devlink)))
|
||||
devlink_reload_netns_change(devlink, dest_net);
|
||||
if (dest_net && !net_eq(dest_net, curr_net))
|
||||
write_pnet(&devlink->_net, dest_net);
|
||||
|
||||
err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
|
||||
devlink_reload_failed_set(devlink, !!err);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
devlink_ns_change_notify(devlink, dest_net, curr_net, true);
|
||||
WARN_ON(!(*actions_performed & BIT(action)));
|
||||
/* Catch driver on updating the remote action within devlink reload */
|
||||
WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
|
||||
@ -8768,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;
|
||||
|
||||
@ -8791,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);
|
||||
@ -8807,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
|
||||
|
Loading…
Reference in New Issue
Block a user