diff options
author | 2023-01-05 22:33:56 -0800 | |
---|---|---|
committer | 2023-01-06 12:56:18 +0000 | |
commit | 870c7ad4a52be2acff92d0355ca118654c7efece (patch) | |
tree | 17e94f028695b80ebf2dfcfc1e94a6b222cf070d /net/devlink/netlink.c | |
parent | devlink: update the code in netns move to latest helpers (diff) | |
download | wireguard-linux-870c7ad4a52be2acff92d0355ca118654c7efece.tar.xz wireguard-linux-870c7ad4a52be2acff92d0355ca118654c7efece.zip |
devlink: protect devlink->dev by the instance lock
devlink->dev is assumed to be always valid as long as any
outstanding reference to the devlink instance exists.
In prep for weakening of the references take the instance lock.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/devlink/netlink.c')
-rw-r--r-- | net/devlink/netlink.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c index a552e723f4a6..69111746f5d9 100644 --- a/net/devlink/netlink.c +++ b/net/devlink/netlink.c @@ -82,7 +82,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_REGION_DIRECT] = { .type = NLA_FLAG }, }; -struct devlink *devlink_get_from_attrs(struct net *net, struct nlattr **attrs) +struct devlink * +devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs) { struct devlink *devlink; unsigned long index; @@ -96,9 +97,11 @@ struct devlink *devlink_get_from_attrs(struct net *net, struct nlattr **attrs) devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); devlinks_xa_for_each_registered_get(net, index, devlink) { + devl_lock(devlink); if (strcmp(devlink->dev->bus->name, busname) == 0 && strcmp(dev_name(devlink->dev), devname) == 0) return devlink; + devl_unlock(devlink); devlink_put(devlink); } @@ -113,10 +116,10 @@ static int devlink_nl_pre_doit(const struct genl_split_ops *ops, struct devlink *devlink; int err; - devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs); + devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs); if (IS_ERR(devlink)) return PTR_ERR(devlink); - devl_lock(devlink); + info->user_ptr[0] = devlink; if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { devlink_port = devlink_port_get_from_info(devlink, info); |