[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <a0475d8c2592852ddfa0663469c96dcb14bdefff.1636390483.git.leonro@nvidia.com>
Date: Mon, 8 Nov 2021 19:05:33 +0200
From: Leon Romanovsky <leon@...nel.org>
To: "David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>
Cc: Leon Romanovsky <leonro@...dia.com>,
Ido Schimmel <idosch@...dia.com>, Jiri Pirko <jiri@...dia.com>,
netdev <netdev@...r.kernel.org>
Subject: [RFC PATCH 11/16] devlink: Protect all rate operations with specialized lock
From: Leon Romanovsky <leonro@...dia.com>
Separate rate related list protection from main devlink instance lock
to rely on specialized lock.
Signed-off-by: Leon Romanovsky <leonro@...dia.com>
---
net/core/devlink.c | 60 +++++++++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 52a1255a0917..008826bc108d 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -43,6 +43,7 @@ struct devlink {
struct list_head port_list;
struct mutex port_list_lock; /* protects port_list */
struct list_head rate_list;
+ struct mutex rate_list_lock; /* protects rate_list */
struct list_head sb_list;
struct list_head dpipe_table_list;
struct list_head resource_list;
@@ -1143,7 +1144,7 @@ static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
goto retry;
- mutex_lock(&devlink->lock);
+ mutex_lock(&devlink->rate_list_lock);
list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
u32 id = NETLINK_CB(cb->skb).portid;
@@ -1156,13 +1157,13 @@ static int devlink_nl_cmd_rate_get_dumpit(struct sk_buff *msg,
cb->nlh->nlmsg_seq,
NLM_F_MULTI, NULL);
if (err) {
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
devlink_put(devlink);
goto out;
}
idx++;
}
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
retry:
devlink_put(devlink);
}
@@ -1829,15 +1830,21 @@ static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
return -EOPNOTSUPP;
+ mutex_lock(&devlink->rate_list_lock);
rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
- if (!IS_ERR(rate_node))
- return -EEXIST;
- else if (rate_node == ERR_PTR(-EINVAL))
- return -EINVAL;
+ if (!IS_ERR(rate_node)) {
+ err = -EEXIST;
+ goto out;
+ } else if (rate_node == ERR_PTR(-EINVAL)) {
+ err = -EINVAL;
+ goto out;
+ }
rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
- if (!rate_node)
- return -ENOMEM;
+ if (!rate_node) {
+ err = -ENOMEM;
+ goto out;
+ }
rate_node->devlink = devlink;
rate_node->type = DEVLINK_RATE_TYPE_NODE;
@@ -1858,6 +1865,7 @@ static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
refcount_set(&rate_node->refcnt, 1);
list_add(&rate_node->list, &devlink->rate_list);
devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
+ mutex_unlock(&devlink->rate_list_lock);
return 0;
err_rate_set:
@@ -1866,6 +1874,8 @@ static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
kfree(rate_node->name);
err_strdup:
kfree(rate_node);
+out:
+ mutex_unlock(&devlink->rate_list_lock);
return err;
}
@@ -2800,14 +2810,14 @@ static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
struct devlink_rate *devlink_rate;
/* Take the lock to sync with devlink_rate_nodes_destroy() */
- mutex_lock(&devlink->lock);
+ mutex_lock(&devlink->rate_list_lock);
list_for_each_entry(devlink_rate, &devlink->rate_list, list)
if (devlink_rate_is_node(devlink_rate)) {
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
return -EBUSY;
}
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
return 0;
}
@@ -9009,6 +9019,8 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
mutex_init(&devlink->port_list_lock);
INIT_LIST_HEAD(&devlink->rate_list);
+ mutex_init(&devlink->rate_list_lock);
+
INIT_LIST_HEAD(&devlink->sb_list);
INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
@@ -9077,8 +9089,10 @@ static void devlink_notify_register(struct devlink *devlink)
devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
mutex_unlock(&devlink->traps_lock);
+ mutex_lock(&devlink->rate_list_lock);
list_for_each_entry(rate_node, &devlink->rate_list, list)
devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
+ mutex_unlock(&devlink->rate_list_lock);
mutex_lock(&devlink->region_list_lock);
list_for_each_entry(region, &devlink->region_list, list)
@@ -9109,8 +9123,10 @@ static void devlink_notify_unregister(struct devlink *devlink)
devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
mutex_unlock(&devlink->region_list_lock);
+ mutex_lock(&devlink->rate_list_lock);
list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
+ mutex_unlock(&devlink->rate_list_lock);
mutex_lock(&devlink->traps_lock);
list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
@@ -9184,6 +9200,7 @@ void devlink_free(struct devlink *devlink)
mutex_destroy(&devlink->resource_list_lock);
mutex_destroy(&devlink->traps_lock);
mutex_destroy(&devlink->region_list_lock);
+ mutex_destroy(&devlink->rate_list_lock);
mutex_destroy(&devlink->lock);
WARN_ON(!list_empty(&devlink->trap_policer_list));
WARN_ON(!list_empty(&devlink->trap_group_list));
@@ -9522,8 +9539,6 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
* Create devlink rate object of type leaf on provided @devlink_port.
* Throws call trace if @devlink_port already has a devlink rate object.
*
- * Context: Takes and release devlink->lock <mutex>.
- *
* Return: -ENOMEM if failed to allocate rate object, 0 otherwise.
*/
int
@@ -9536,16 +9551,17 @@ devlink_rate_leaf_create(struct devlink_port *devlink_port, void *priv)
if (!devlink_rate)
return -ENOMEM;
- mutex_lock(&devlink->lock);
WARN_ON(devlink_port->devlink_rate);
devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
devlink_rate->devlink = devlink;
devlink_rate->devlink_port = devlink_port;
devlink_rate->priv = priv;
+
+ mutex_lock(&devlink->rate_list_lock);
list_add_tail(&devlink_rate->list, &devlink->rate_list);
devlink_port->devlink_rate = devlink_rate;
devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
return 0;
}
@@ -9555,8 +9571,6 @@ EXPORT_SYMBOL_GPL(devlink_rate_leaf_create);
* devlink_rate_leaf_destroy - destroy devlink rate leaf
*
* @devlink_port: devlink port linked to the rate object
- *
- * Context: Takes and release devlink->lock <mutex>.
*/
void devlink_rate_leaf_destroy(struct devlink_port *devlink_port)
{
@@ -9566,13 +9580,13 @@ void devlink_rate_leaf_destroy(struct devlink_port *devlink_port)
if (!devlink_rate)
return;
- mutex_lock(&devlink->lock);
+ mutex_lock(&devlink->rate_list_lock);
devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
if (devlink_rate->parent)
refcount_dec(&devlink_rate->parent->refcnt);
list_del(&devlink_rate->list);
devlink_port->devlink_rate = NULL;
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
kfree(devlink_rate);
}
EXPORT_SYMBOL_GPL(devlink_rate_leaf_destroy);
@@ -9584,15 +9598,13 @@ EXPORT_SYMBOL_GPL(devlink_rate_leaf_destroy);
*
* Unset parent for all rate objects and destroy all rate nodes
* on specified device.
- *
- * Context: Takes and release devlink->lock <mutex>.
*/
void devlink_rate_nodes_destroy(struct devlink *devlink)
{
static struct devlink_rate *devlink_rate, *tmp;
const struct devlink_ops *ops = devlink->ops;
- mutex_lock(&devlink->lock);
+ mutex_lock(&devlink->rate_list_lock);
list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
if (!devlink_rate->parent)
continue;
@@ -9613,7 +9625,7 @@ void devlink_rate_nodes_destroy(struct devlink *devlink)
kfree(devlink_rate);
}
}
- mutex_unlock(&devlink->lock);
+ mutex_unlock(&devlink->rate_list_lock);
}
EXPORT_SYMBOL_GPL(devlink_rate_nodes_destroy);
--
2.33.1
Powered by blists - more mailing lists