]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
devlink: Refactor devlink_rate_nodes_check
authorCosmin Ratiu <cratiu@nvidia.com>
Wed, 28 Jan 2026 11:25:35 +0000 (13:25 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 3 Feb 2026 04:05:51 +0000 (20:05 -0800)
devlink_rate_nodes_check() was used to verify there are no devlink rate
nodes created when switching the esw mode.

Rate management code is about to become more complex, so refactor this
function:
- remove unused param 'mode'.
- add a new 'rate_filter' param.
- rename to devlink_rates_check().
- expose devlink_rate_is_node() to be used as a rate filter.

This makes it more usable from multiple places, so use it from those
places as well.

Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260128112544.1661250-6-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/devlink/core.c
net/devlink/dev.c
net/devlink/devl_internal.h
net/devlink/rate.c

index 6ae62c7f2a80adafbf8ddf4ccdc713ddd76ba753..da56e2b8afc1d4887225944e447f2d7b5aa31fad 100644 (file)
@@ -475,7 +475,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(devlink_rates_check(devlink, NULL, NULL));
        WARN_ON(!list_empty(&devlink->linecard_list));
        WARN_ON(!xa_empty(&devlink->ports));
 
index 02602704bdeaa270545f7afe78a9d33d4e45f62d..e3a36de4f4aec410434b1e6cadc5fb888ea3e02b 100644 (file)
@@ -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(devlink_rates_check(devlink, NULL, NULL));
        WARN_ON(!list_empty(&devlink->linecard_list));
        WARN_ON(!xa_empty(&devlink->ports));
 }
@@ -713,10 +713,11 @@ int devlink_nl_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
                if (!ops->eswitch_mode_set)
                        return -EOPNOTSUPP;
-               mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
-               err = devlink_rate_nodes_check(devlink, mode, info->extack);
+               err = devlink_rates_check(devlink, devlink_rate_is_node,
+                                         info->extack);
                if (err)
                        return err;
+               mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
                err = ops->eswitch_mode_set(devlink, mode, info->extack);
                if (err)
                        return err;
index 14eaad9cfe35718f38c401ad1b01df9595f58c85..1377864383bc265592d506bf548395a744d8c30d 100644 (file)
@@ -297,8 +297,10 @@ int devlink_resources_validate(struct devlink *devlink,
                               struct genl_info *info);
 
 /* Rates */
-int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
-                            struct netlink_ext_ack *extack);
+bool devlink_rate_is_node(const struct devlink_rate *devlink_rate);
+int devlink_rates_check(struct devlink *devlink,
+                       bool (*rate_filter)(const struct devlink_rate *),
+                       struct netlink_ext_ack *extack);
 
 /* Linecards */
 unsigned int devlink_linecard_index(struct devlink_linecard *linecard);
index d157a8419bcad4dfbde0a3b4acb2b1575da941ee..0d68b5c477dc978f038257e153f9bdf6e34d34af 100644 (file)
@@ -12,8 +12,7 @@ devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
        return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
 }
 
-static inline bool
-devlink_rate_is_node(struct devlink_rate *devlink_rate)
+bool devlink_rate_is_node(const struct devlink_rate *devlink_rate)
 {
        return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
 }
@@ -688,14 +687,16 @@ int devlink_nl_rate_del_doit(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
-int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
-                            struct netlink_ext_ack *extack)
+int devlink_rates_check(struct devlink *devlink,
+                       bool (*rate_filter)(const struct devlink_rate *),
+                       struct netlink_ext_ack *extack)
 {
        struct devlink_rate *devlink_rate;
 
        list_for_each_entry(devlink_rate, &devlink->rate_list, list)
-               if (devlink_rate_is_node(devlink_rate)) {
-                       NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
+               if (!rate_filter || rate_filter(devlink_rate)) {
+                       if (extack)
+                               NL_SET_ERR_MSG(extack, "Rate node(s) exists.");
                        return -EBUSY;
                }
        return 0;