mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-23 00:20:52 -05:00
devlink: Allow taking device lock in pre_doit operations
Introduce a new private flag ('DEVLINK_NL_FLAG_NEED_DEV_LOCK') to allow netlink commands to specify that they need to acquire the device lock in their pre_doit operation and release it in their post_doit operation. The reload command will use this flag in the subsequent patch. No functional changes intended. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c8d0a7d615
commit
d32c38256d
4 changed files with 18 additions and 10 deletions
|
@ -152,7 +152,8 @@ typedef int devlink_nl_dump_one_func_t(struct sk_buff *msg,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
struct devlink *
|
struct devlink *
|
||||||
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs);
|
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
|
||||||
|
bool dev_lock);
|
||||||
|
|
||||||
int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
|
int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
|
||||||
devlink_nl_dump_one_func_t *dump_one);
|
devlink_nl_dump_one_func_t *dump_one);
|
||||||
|
|
|
@ -1151,7 +1151,8 @@ devlink_health_reporter_get_from_cb_lock(struct netlink_callback *cb)
|
||||||
struct nlattr **attrs = info->attrs;
|
struct nlattr **attrs = info->attrs;
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
|
|
||||||
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
|
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs,
|
||||||
|
false);
|
||||||
if (IS_ERR(devlink))
|
if (IS_ERR(devlink))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
|
#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
|
||||||
#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
|
#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
|
||||||
|
#define DEVLINK_NL_FLAG_NEED_DEV_LOCK BIT(2)
|
||||||
|
|
||||||
static const struct genl_multicast_group devlink_nl_mcgrps[] = {
|
static const struct genl_multicast_group devlink_nl_mcgrps[] = {
|
||||||
[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
|
[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
|
||||||
|
@ -64,7 +65,8 @@ int devlink_nl_msg_reply_and_new(struct sk_buff **msg, struct genl_info *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct devlink *
|
struct devlink *
|
||||||
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs)
|
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
|
||||||
|
bool dev_lock)
|
||||||
{
|
{
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
|
@ -78,12 +80,12 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs)
|
||||||
devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
|
devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
|
||||||
|
|
||||||
devlinks_xa_for_each_registered_get(net, index, devlink) {
|
devlinks_xa_for_each_registered_get(net, index, devlink) {
|
||||||
devl_lock(devlink);
|
devl_dev_lock(devlink, dev_lock);
|
||||||
if (devl_is_registered(devlink) &&
|
if (devl_is_registered(devlink) &&
|
||||||
strcmp(devlink->dev->bus->name, busname) == 0 &&
|
strcmp(devlink->dev->bus->name, busname) == 0 &&
|
||||||
strcmp(dev_name(devlink->dev), devname) == 0)
|
strcmp(dev_name(devlink->dev), devname) == 0)
|
||||||
return devlink;
|
return devlink;
|
||||||
devl_unlock(devlink);
|
devl_dev_unlock(devlink, dev_lock);
|
||||||
devlink_put(devlink);
|
devlink_put(devlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,11 +95,13 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs)
|
||||||
static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
|
static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
|
||||||
u8 flags)
|
u8 flags)
|
||||||
{
|
{
|
||||||
|
bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
|
||||||
struct devlink_port *devlink_port;
|
struct devlink_port *devlink_port;
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs);
|
devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs,
|
||||||
|
dev_lock);
|
||||||
if (IS_ERR(devlink))
|
if (IS_ERR(devlink))
|
||||||
return PTR_ERR(devlink);
|
return PTR_ERR(devlink);
|
||||||
|
|
||||||
|
@ -117,7 +121,7 @@ static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
devl_unlock(devlink);
|
devl_dev_unlock(devlink, dev_lock);
|
||||||
devlink_put(devlink);
|
devlink_put(devlink);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -144,10 +148,11 @@ int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops,
|
||||||
static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info,
|
static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info,
|
||||||
u8 flags)
|
u8 flags)
|
||||||
{
|
{
|
||||||
|
bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
|
|
||||||
devlink = info->user_ptr[0];
|
devlink = info->user_ptr[0];
|
||||||
devl_unlock(devlink);
|
devl_dev_unlock(devlink, dev_lock);
|
||||||
devlink_put(devlink);
|
devlink_put(devlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +170,7 @@ static int devlink_nl_inst_single_dumpit(struct sk_buff *msg,
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs);
|
devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs, false);
|
||||||
if (IS_ERR(devlink))
|
if (IS_ERR(devlink))
|
||||||
return PTR_ERR(devlink);
|
return PTR_ERR(devlink);
|
||||||
err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED);
|
err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED);
|
||||||
|
|
|
@ -883,7 +883,8 @@ int devlink_nl_region_read_dumpit(struct sk_buff *skb,
|
||||||
|
|
||||||
start_offset = state->start_offset;
|
start_offset = state->start_offset;
|
||||||
|
|
||||||
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
|
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs,
|
||||||
|
false);
|
||||||
if (IS_ERR(devlink))
|
if (IS_ERR(devlink))
|
||||||
return PTR_ERR(devlink);
|
return PTR_ERR(devlink);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue