From: Tariq Toukan <tariqt@nvidia.com>
To: "David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Eric Dumazet <edumazet@google.com>,
"Andrew Lunn" <andrew+netdev@lunn.ch>,
Jiri Pirko <jiri@nvidia.com>
Cc: Cosmin Ratiu <cratiu@nvidia.com>,
Carolina Jubran <cjubran@nvidia.com>,
Gal Pressman <gal@nvidia.com>, Mark Bloch <mbloch@nvidia.com>,
Donald Hunter <donald.hunter@gmail.com>,
Jiri Pirko <jiri@resnulli.us>, Jonathan Corbet <corbet@lwn.net>,
Saeed Mahameed <saeedm@nvidia.com>,
Leon Romanovsky <leon@kernel.org>,
Tariq Toukan <tariqt@nvidia.com>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <linux-doc@vger.kernel.org>,
<linux-rdma@vger.kernel.org>
Subject: [PATCH net-next 02/10] devlink: Store devlink rates in a rate domain
Date: Thu, 13 Feb 2025 20:01:26 +0200 [thread overview]
Message-ID: <20250213180134.323929-3-tariqt@nvidia.com> (raw)
In-Reply-To: <20250213180134.323929-1-tariqt@nvidia.com>
From: Cosmin Ratiu <cratiu@nvidia.com>
Introduce the concept of a rate domain, a data structure aiming to store
devlink rates of one or more devlink objects such that rate nodes within
a rate domain can be parents of other rate nodes from the same domain.
This commit takes the first steps in that direction by:
- introducing a new 'devlink_rate_domain' data structure, allocated on
devlink init.
- storing devlink rates from the devlink object into the rate domain.
- converting all accesses to the new data structure.
- adding checks for everything that walks rates in a rate domain so that
the correct devlink object is looked at. These checks are now spurious
since all rate domains are private to their devlink object, but that
is about to change and this is a good moment to add those checks.
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
net/devlink/core.c | 11 ++++++++--
net/devlink/dev.c | 2 +-
net/devlink/devl_internal.h | 7 ++++++-
net/devlink/rate.c | 41 ++++++++++++++++++++++---------------
4 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index f49cd83f1955..06a2e2dce558 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -314,6 +314,7 @@ static void devlink_release(struct work_struct *work)
mutex_destroy(&devlink->lock);
lockdep_unregister_key(&devlink->lock_key);
put_device(devlink->dev);
+ kvfree(devlink->rate_domain);
kvfree(devlink);
}
@@ -424,6 +425,11 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
if (!devlink)
return NULL;
+ devlink->rate_domain = kvzalloc(sizeof(*devlink->rate_domain), GFP_KERNEL);
+ if (!devlink->rate_domain)
+ goto err_rate_domain;
+ INIT_LIST_HEAD(&devlink->rate_domain->rate_list);
+
ret = xa_alloc_cyclic(&devlinks, &devlink->index, devlink, xa_limit_31b,
&last_id, GFP_KERNEL);
if (ret < 0)
@@ -436,7 +442,6 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
xa_init_flags(&devlink->nested_rels, XA_FLAGS_ALLOC);
write_pnet(&devlink->_net, net);
- INIT_LIST_HEAD(&devlink->rate_list);
INIT_LIST_HEAD(&devlink->linecard_list);
INIT_LIST_HEAD(&devlink->sb_list);
INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
@@ -455,6 +460,8 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
return devlink;
err_xa_alloc:
+ kvfree(devlink->rate_domain);
+err_rate_domain:
kvfree(devlink);
return NULL;
}
@@ -477,7 +484,7 @@ void devlink_free(struct devlink *devlink)
WARN_ON(!list_empty(&devlink->resource_list));
WARN_ON(!list_empty(&devlink->dpipe_table_list));
WARN_ON(!list_empty(&devlink->sb_list));
- WARN_ON(!list_empty(&devlink->rate_list));
+ WARN_ON(!list_empty(&devlink->rate_domain->rate_list));
WARN_ON(!list_empty(&devlink->linecard_list));
WARN_ON(!xa_empty(&devlink->ports));
diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index 5ff5d9055a8d..c926c75cc10d 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c
@@ -434,7 +434,7 @@ static void devlink_reload_reinit_sanity_check(struct devlink *devlink)
WARN_ON(!list_empty(&devlink->trap_list));
WARN_ON(!list_empty(&devlink->dpipe_table_list));
WARN_ON(!list_empty(&devlink->sb_list));
- WARN_ON(!list_empty(&devlink->rate_list));
+ WARN_ON(!list_empty(&devlink->rate_domain->rate_list));
WARN_ON(!list_empty(&devlink->linecard_list));
WARN_ON(!xa_empty(&devlink->ports));
}
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 9cc7a5f4a19f..209b4a4c7070 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -30,10 +30,14 @@ struct devlink_dev_stats {
u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
};
+/* Stores devlink rates associated with a rate domain. */
+struct devlink_rate_domain {
+ struct list_head rate_list;
+};
+
struct devlink {
u32 index;
struct xarray ports;
- struct list_head rate_list;
struct list_head sb_list;
struct list_head dpipe_table_list;
struct list_head resource_list;
@@ -55,6 +59,7 @@ struct devlink {
*/
struct mutex lock;
struct lock_class_key lock_key;
+ struct devlink_rate_domain *rate_domain;
u8 reload_failed:1;
refcount_t refcount;
struct rcu_work rwork;
diff --git a/net/devlink/rate.c b/net/devlink/rate.c
index d163c61cdd98..535863bb0c17 100644
--- a/net/devlink/rate.c
+++ b/net/devlink/rate.c
@@ -36,8 +36,9 @@ devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
{
static struct devlink_rate *devlink_rate;
- list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
- if (devlink_rate_is_node(devlink_rate) &&
+ list_for_each_entry(devlink_rate, &devlink->rate_domain->rate_list, list) {
+ if (devlink_rate->devlink == devlink &&
+ devlink_rate_is_node(devlink_rate) &&
!strcmp(node_name, devlink_rate->name))
return devlink_rate;
}
@@ -166,16 +167,18 @@ void devlink_rates_notify_register(struct devlink *devlink)
{
struct devlink_rate *rate_node;
- list_for_each_entry(rate_node, &devlink->rate_list, list)
- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
+ list_for_each_entry(rate_node, &devlink->rate_domain->rate_list, list)
+ if (rate_node->devlink == devlink)
+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
}
void devlink_rates_notify_unregister(struct devlink *devlink)
{
struct devlink_rate *rate_node;
- list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
- devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
+ list_for_each_entry_reverse(rate_node, &devlink->rate_domain->rate_list, list)
+ if (rate_node->devlink == devlink)
+ devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
}
static int
@@ -187,7 +190,7 @@ devlink_nl_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
int idx = 0;
int err = 0;
- list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
+ list_for_each_entry(devlink_rate, &devlink->rate_domain->rate_list, list) {
enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
u32 id = NETLINK_CB(cb->skb).portid;
@@ -195,6 +198,9 @@ devlink_nl_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
idx++;
continue;
}
+ if (devlink_rate->devlink != devlink)
+ continue;
+
err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
cb->nlh->nlmsg_seq, flags, NULL);
if (err) {
@@ -522,7 +528,7 @@ int devlink_nl_rate_new_doit(struct sk_buff *skb, struct genl_info *info)
goto err_rate_set;
refcount_set(&rate_node->refcnt, 1);
- list_add(&rate_node->list, &devlink->rate_list);
+ list_add(&rate_node->list, &devlink->rate_domain->rate_list);
devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
return 0;
@@ -565,8 +571,9 @@ int devlink_rate_nodes_check(struct devlink *devlink, struct netlink_ext_ack *ex
{
struct devlink_rate *devlink_rate;
- list_for_each_entry(devlink_rate, &devlink->rate_list, list)
- if (devlink_rate_is_node(devlink_rate)) {
+ list_for_each_entry(devlink_rate, &devlink->rate_domain->rate_list, list)
+ if (devlink_rate->devlink == devlink &&
+ devlink_rate_is_node(devlink_rate)) {
NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
return -EBUSY;
}
@@ -612,7 +619,7 @@ devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
}
refcount_set(&rate_node->refcnt, 1);
- list_add(&rate_node->list, &devlink->rate_list);
+ list_add(&rate_node->list, &devlink->rate_domain->rate_list);
devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
return rate_node;
}
@@ -650,7 +657,7 @@ int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
devlink_rate->devlink = devlink;
devlink_rate->devlink_port = devlink_port;
devlink_rate->priv = priv;
- list_add_tail(&devlink_rate->list, &devlink->rate_list);
+ list_add_tail(&devlink_rate->list, &devlink->rate_domain->rate_list);
devlink_port->devlink_rate = devlink_rate;
devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
@@ -691,13 +698,13 @@ EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
*/
void devl_rate_nodes_destroy(struct devlink *devlink)
{
- static struct devlink_rate *devlink_rate, *tmp;
+ struct devlink_rate *devlink_rate, *tmp;
const struct devlink_ops *ops = devlink->ops;
devl_assert_locked(devlink);
- list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
- if (!devlink_rate->parent)
+ list_for_each_entry(devlink_rate, &devlink->rate_domain->rate_list, list) {
+ if (!devlink_rate->parent || devlink_rate->devlink != devlink)
continue;
refcount_dec(&devlink_rate->parent->refcnt);
@@ -708,8 +715,8 @@ void devl_rate_nodes_destroy(struct devlink *devlink)
ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
NULL, NULL);
}
- list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
- if (devlink_rate_is_node(devlink_rate)) {
+ list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_domain->rate_list, list) {
+ if (devlink_rate->devlink == devlink && devlink_rate_is_node(devlink_rate)) {
ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
list_del(&devlink_rate->list);
kfree(devlink_rate->name);
--
2.45.0
next prev parent reply other threads:[~2025-02-13 18:02 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-13 18:01 [PATCH net-next 00/10] devlink and mlx5: Introduce rate domains Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 01/10] devlink: Remove unused param of devlink_rate_nodes_check Tariq Toukan
2025-02-18 2:54 ` Kalesh Anakkur Purayil
2025-02-13 18:01 ` Tariq Toukan [this message]
2025-02-13 18:01 ` [PATCH net-next 03/10] devlink: Serialize access to rate domains Tariq Toukan
2025-02-14 12:54 ` Jiri Pirko
2025-02-19 2:21 ` Jakub Kicinski
2025-02-25 13:36 ` Jiri Pirko
2025-02-26 1:40 ` Jakub Kicinski
2025-02-26 14:44 ` Jiri Pirko
2025-02-27 2:53 ` Jakub Kicinski
2025-02-27 12:22 ` Jiri Pirko
2025-03-03 22:06 ` Jakub Kicinski
2025-03-04 13:11 ` Jiri Pirko
2025-03-05 0:04 ` Jakub Kicinski
2025-03-05 11:48 ` Jiri Pirko
2025-02-13 18:01 ` [PATCH net-next 04/10] devlink: Introduce shared " Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 05/10] devlink: Allow specifying parent device for rate commands Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 06/10] devlink: Allow rate node parents from other devlinks Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 07/10] net/mlx5: qos: Introduce shared esw qos domains Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 08/10] net/mlx5: qos: Support cross-esw tx scheduling Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 09/10] net/mlx5: qos: Init shared devlink rate domain Tariq Toukan
2025-02-13 18:01 ` [PATCH net-next 10/10] net/mlx5: Document devlink rates and cross-esw scheduling Tariq Toukan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250213180134.323929-3-tariqt@nvidia.com \
--to=tariqt@nvidia.com \
--cc=andrew+netdev@lunn.ch \
--cc=cjubran@nvidia.com \
--cc=corbet@lwn.net \
--cc=cratiu@nvidia.com \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=gal@nvidia.com \
--cc=jiri@nvidia.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox