devlink: add per-port resource support
Subsystems (9)
Tariq Toukan
maintainerv5 cover devlink: add per-port resource support
Hi,
This series by Or adds devlink per-port resource support. See detailed description by Or below [1].
Regards,
Tariq
[1]
Currently, devlink resources are only available at the device level. However, some resources are inherently per-port, such as the maximum number of subfunctions (SFs) that can be created on a specific PF port. This limitation prevents user space from obtaining accurate per-port capacity information.
This series adds infrastructure for per-port resources in devlink core and implements it in the mlx5 driver to expose the max_SFs resource on PF devlink ports.
Patch #1 refactors resource functions to be generic Patch #2 adds port-level resource registration infrastructure Patch #3 registers SF resource on PF port representor in mlx5 Patch #4 adds devlink port resource registration to netdevsim for testing Patch #5 adds dump support for device-level resources Patch #6 includes port resources in the resource dump dumpit path Patch #7 adds port-specific option to resource dump doit path Patch #8 adds selftest for devlink port resource doit Patch #9 documents port-level resources and full dump
Patch #10 adds resource scope filtering to resource dump Patch #11 adds selftest for resource dump and scope filter Patch #12 documents resource scope filtering
Userspace patches for iproute2:
https://github.com/ohartoov/iproute2/tree/port_resources
V5:
- Link to V4:
https://lore.kernel.org/all/[email protected]/
- Change resource scope attribute from bitmask to u32
- Remove max value and valid mask define for scope attribute
- Handle the case where a device is unregistered or a port is removed in the middle of a multi-callback dump (Sashiko's comment)
- Replace port_number with port_index and add an index_valid bool to the dump state to track the port resources phase of the dump (Sashiko's comment)
Or Har-Toov (12):
devlink: Refactor resource functions to be generic
devlink: Add port-level resource registration infrastructure net/mlx5: Register SF resource on PF port representor
netdevsim: Add devlink port resource registration
devlink: Add dump support for device-level resources
devlink: Include port resources in resource dump dumpit
devlink: Add port-specific option to resource dump doit
selftest: netdevsim: Add devlink port resource doit test
devlink: Document port-level resources and full dump
devlink: Add resource scope filtering to resource dump
selftest: netdevsim: Add resource dump and scope filter test
devlink: Document resource scope filtering
Documentation/netlink/specs/devlink.yaml | 32 +- .../networking/devlink/devlink-resource.rst | 70 ++++ .../net/ethernet/mellanox/mlx5/core/devlink.h | 4 + .../mellanox/mlx5/core/esw/devlink_port.c | 37 +++ drivers/net/netdevsim/dev.c | 23 +- drivers/net/netdevsim/netdevsim.h | 4 + include/net/devlink.h | 10 +- include/uapi/linux/devlink.h | 11 + net/devlink/devl_internal.h | 5 + net/devlink/netlink.c | 2 + net/devlink/netlink_gen.c | 24 +- net/devlink/netlink_gen.h | 8 +- net/devlink/port.c | 2 + net/devlink/resource.c | 314 +++++++++++++++--- .../drivers/net/netdevsim/devlink.sh | 79 ++++- 15 files changed, 568 insertions(+), 57 deletions(-)
base-commit: c149d90e260ca1b6b9175468955a15c4d95a9f3b
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 1/12 devlink: Refactor resource functions to be generic
From: Or Har-Toov <[email protected]>
Currently the resource functions take devlink pointer as parameter and take the resource list from there.
Allow resource functions to work with other resource lists that will be added in next patches and not only with the devlink's resource list.
--- include/net/devlink.h | 2 +- net/devlink/resource.c | 114 ++++++++++++++++++++++++++--------------- 2 files changed, 73 insertions(+), 43 deletions(-)
include/net/devlink.h +1 -1
@@ -1885,7 +1885,7 @@ int devl_resource_register(struct devlink *devlink,u64 resource_size, u64 resource_id, u64 parent_resource_id, - const struct devlink_resource_size_params *size_params); + const struct devlink_resource_size_params *params);void devl_resources_unregister (struct devlink *devlink);void devlink_resources_unregister (struct devlink *devlink); int devl_resource_size_get(struct devlink *devlink,
net/devlink/resource.c +72 -42
192 lines not on this page · raw message
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 2/12 devlink: Add port-level resource registration infrastructure
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
The current devlink resource infrastructure supports only device-level resources. Some hardware resources are associated with specific ports rather than the entire device, and today we have no way to show resource per-port.
Add support for registering resources at the port level.
--- include/net/devlink.h | 8 ++++++++ net/devlink/port.c | 2 ++ net/devlink/resource.c | 43 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+)
include/net/devlink.h +8 -0
@@ -129,6 +129,7 @@ struct devlink_rate {struct devlink_port {struct list_head list;struct list_head region_list; +struct list_head resource_list;struct devlink *devlink;const struct devlink_port_ops *ops;unsigned int index;
@@ -1891,6 +1892,13 @@ void devlink_resources_unregister(struct devlink *devlink);int devl_resource_size_get (struct devlink *devlink,u64 resource_id,u64 *p_resource_size); +int +devl_port_resource_register (struct devlink_port *devlink_port, +const char *resource_name, +u64 resource_size,u64 resource_id, +u64 parent_resource_id, +const struct devlink_resource_size_params *params); +void devl_port_resources_unregister (struct devlink_port *devlink_port);int devl_dpipe_table_resource_set (struct devlink *devlink,const char *table_name,u64 resource_id,u64 resource_units);
net/devlink/port.c +2 -0
@@ -1025,6 +1025,7 @@ void devlink_port_init(struct devlink *devlink,return ; devlink_port->devlink = devlink;INIT_LIST_HEAD (&devlink_port->region_list); +INIT_LIST_HEAD (&devlink_port->resource_list); devlink_port->initialized = true; }EXPORT_SYMBOL_GPL (devlink_port_init);
@@ -1042,6 +1043,7 @@ EXPORT_SYMBOL_GPL(devlink_port_init);void devlink_port_fini (struct devlink_port *devlink_port) {WARN_ON (!list_empty (&devlink_port->region_list)); +WARN_ON (!list_empty (&devlink_port->resource_list)); }EXPORT_SYMBOL_GPL (devlink_port_fini);
net/devlink/resource.c +43 -0
46 lines not on this page · raw message
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 3/12 net/mlx5: Register SF resource on PF port representor
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
The device-level "resource show" displays max_local_SFs and max_external_SFs without indicating which port each resource belongs to. Users cannot determine the controller number and pfnum associated with each SF pool.
Register max_SFs resource on the host PF representor port to expose per-port SF limits. Users can correlate the port resource with the controller number and pfnum shown in 'devlink port show'.
Future patches will introduce an ECPF that manages multiple PFs, where each PF has its own SF pool.
Example usage:
$ devlink resource show pci/0000:03:00.0/196608
pci/0000:03:00.0/196608:
name max_SFs size 20 unit entry $ devlink port show pci/0000:03:00.0/196608
pci/0000:03:00.0/196608: type eth netdev pf0hpf flavour pcipf
controller 1 pfnum 0 external true splittable false
function:
hw_addr b8:3f:d2:e1:8f:dc roce enable max_io_eqs 120We can create up to 20 SFs over devlink port pci/0000:03:00.0/196608, with pfnum 0 and controller 1.
--- .../net/ethernet/mellanox/mlx5/core/devlink.h | 4 ++ .../mellanox/mlx5/core/esw/devlink_port.c | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/devlink.h +4 -0
@@ -14,6 +14,10 @@ enum mlx5_devlink_resource_id { MLX5_ID_RES_MAX = __MLX5_ID_RES_MAX - 1, }; +enum mlx5_devlink_port_resource_id { +MLX5_DL_PORT_RES_MAX_SFS =1 , +}; +enum mlx5_devlink_param_id {MLX5_DEVLINK_PARAM_ID_BASE =DEVLINK_PARAM_GENERIC_ID_MAX ,MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE ,
drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c +37 -0
@@ -3,6 +3,7 @@#include <linux/mlx5/driver.h> #include "eswitch.h" +#include "devlink.h" static void mlx5_esw_get_port_parent_id (struct mlx5_core_dev *dev,struct netdev_phys_item_id *ppid)
@@ -158,6 +159,32 @@ static const struct devlink_port_ops mlx5_esw_dl_sf_port_ops = { .port_fn_max_io_eqs_set = mlx5_devlink_port_fn_max_io_eqs_set, }; +static int mlx5_esw_devlink_port_res_register (struct mlx5_eswitch *esw, +struct devlink_port *dl_port) +{ +struct devlink_resource_size_params size_params; +struct mlx5_core_dev *dev = esw->dev; +u16 max_sfs, sf_base_id; +int err; + + err =mlx5_esw_sf_max_hpf_functions (dev, &max_sfs, &sf_base_id); +if (err) +return err; + +devlink_resource_size_params_init (&size_params, max_sfs, max_sfs,1 , +DEVLINK_RESOURCE_UNIT_ENTRY ); + +return devl_port_resource_register (dl_port,"max_SFs" , max_sfs, +MLX5_DL_PORT_RES_MAX_SFS , +DEVLINK_RESOURCE_ID_PARENT_TOP , + &size_params); +} + +static void mlx5_esw_devlink_port_res_unregister (struct devlink_port *dl_port) +{ +devl_port_resources_unregister (dl_port); +} +int mlx5_esw_offloads_devlink_port_register (struct mlx5_eswitch *esw,struct mlx5_vport *vport) {struct mlx5_core_dev *dev = esw->dev;
@@ -189,6 +216,15 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlxif (err) goto rate_err; +if (vport_num ==MLX5_VPORT_PF ) { + err =mlx5_esw_devlink_port_res_register (esw, + &dl_port->dl_port); +if (err) +mlx5_core_dbg (dev, +"Failed to register port resources: %d\n" , + err); + } +return 0 ; rate_err:
@@ -203,6 +239,7 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_vport *vport)if (!vport->dl_port)return ; dl_port = vport->dl_port; +mlx5_esw_devlink_port_res_unregister (&dl_port->dl_port);mlx5_esw_qos_vport_update_parent (vport,NULL ,NULL );devl_rate_leaf_destroy (&dl_port->dl_port);
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 4/12 netdevsim: Add devlink port resource registration
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Register port-level resources for netdevsim ports to enable testing of the port resource infrastructure.
--- drivers/net/netdevsim/dev.c | 23 ++++++++++++++++++++++- drivers/net/netdevsim/netdevsim.h | 4 ++++ 2 files changed, 26 insertions(+), 1 deletion(-)
drivers/net/netdevsim/dev.c +22 -1
@@ -1486,9 +1486,25 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typif (err) goto err_port_free; +if (nsim_dev_port_is_pf (nsim_dev_port)) { +u64 parent_id =DEVLINK_RESOURCE_ID_PARENT_TOP ; +struct devlink_resource_size_params params = { + .size_max =100 , + .size_granularity =1 , + .unit =DEVLINK_RESOURCE_UNIT_ENTRY + }; + + err =devl_port_resource_register (devlink_port, +"test_resource" ,20 , +NSIM_PORT_RESOURCE_TEST , + parent_id, ¶ms); +if (err) + goto err_dl_port_unregister; + } + err =nsim_dev_port_debugfs_init (nsim_dev, nsim_dev_port);if (err) - goto err_dl_port_unregister; + goto err_port_resource_unregister; nsim_dev_port->ns =nsim_create (nsim_dev, nsim_dev_port, perm_addr);if (IS_ERR (nsim_dev_port->ns)) {
@@ -1511,6 +1527,9 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typnsim_destroy (nsim_dev_port->ns); err_port_debugfs_exit:nsim_dev_port_debugfs_exit (nsim_dev_port); +err_port_resource_unregister: +if (nsim_dev_port_is_pf (nsim_dev_port)) +devl_port_resources_unregister (devlink_port); err_dl_port_unregister:devl_port_unregister (devlink_port); err_port_free:
@@ -1527,6 +1546,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)devl_rate_leaf_destroy (&nsim_dev_port->devlink_port);nsim_destroy (nsim_dev_port->ns);nsim_dev_port_debugfs_exit (nsim_dev_port); +if (nsim_dev_port_is_pf (nsim_dev_port)) +devl_port_resources_unregister (devlink_port);devl_port_unregister (devlink_port);kfree (nsim_dev_port); }
drivers/net/netdevsim/netdevsim.h +4 -0
@@ -224,6 +224,10 @@ enum nsim_resource_id { NSIM_RESOURCE_NEXTHOPS, }; +enum nsim_port_resource_id { +NSIM_PORT_RESOURCE_TEST =1 , +}; +struct nsim_dev_health {struct devlink_health_reporter *empty_reporter;struct devlink_health_reporter *dummy_reporter;
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 5/12 devlink: Add dump support for device-level resources
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Add dumpit handler for resource-dump command to iterate over all devlink devices and show their resources.
$ devlink resource show
pci/0000:08:00.0:
name local_max_SFs size 508 unit entry
name external_max_SFs size 508 unit entry
pci/0000:08:00.1:
name local_max_SFs size 508 unit entry
name external_max_SFs size 508 unit entry--- Documentation/netlink/specs/devlink.yaml | 6 +- net/devlink/netlink_gen.c | 20 +++++- net/devlink/netlink_gen.h | 4 +- net/devlink/resource.c | 77 ++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-)
Documentation/netlink/specs/devlink.yaml +5 -1
@@ -1764,13 +1764,17 @@ operations: - bus-name - dev-name - index - reply: + reply: &resource-dump-reply value: 36 attributes: - bus-name - dev-name - index - resource-list + dump: + request: + attributes: *dev-id-attrs + reply: *resource-dump-reply - name: reload
net/devlink/netlink_gen.c +17 -3
@@ -305,7 +305,14 @@ static const struct nla_policy devlink_resource_set_nl_policy[DEVLINK_ATTR_INDEX };/* DEVLINK_CMD_RESOURCE_DUMP - do */ -static const struct nla_policy devlink_resource_dump_nl_policy[DEVLINK_ATTR_INDEX +1 ] = { +static const struct nla_policy devlink_resource_dump_do_nl_policy[DEVLINK_ATTR_INDEX +1 ] = { + [DEVLINK_ATTR_BUS_NAME ] = { .type =NLA_NUL_STRING , }, + [DEVLINK_ATTR_DEV_NAME ] = { .type =NLA_NUL_STRING , }, + [DEVLINK_ATTR_INDEX ] =NLA_POLICY_FULL_RANGE (NLA_UINT , &devlink_attr_index_range), +}; + +/* DEVLINK_CMD_RESOURCE_DUMP - dump */ +static const struct nla_policy devlink_resource_dump_dump_nl_policy[DEVLINK_ATTR_INDEX +1 ] = { [DEVLINK_ATTR_BUS_NAME ] = { .type =NLA_NUL_STRING , }, [DEVLINK_ATTR_DEV_NAME ] = { .type =NLA_NUL_STRING , }, [DEVLINK_ATTR_INDEX ] =NLA_POLICY_FULL_RANGE (NLA_UINT , &devlink_attr_index_range),
@@ -680,7 +687,7 @@ static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_ };/* Ops table for devlink */ -const struct genl_split_ops devlink_nl_ops[74 ] = { +const struct genl_split_ops devlink_nl_ops[75 ] = { { .cmd =DEVLINK_CMD_GET , .validate =GENL_DONT_VALIDATE_STRICT ,
@@ -958,10 +965,17 @@ const struct genl_split_ops devlink_nl_ops[74] = { .pre_doit = devlink_nl_pre_doit, .doit = devlink_nl_resource_dump_doit, .post_doit = devlink_nl_post_doit, - .policy = devlink_resource_dump_nl_policy, + .policy = devlink_resource_dump_do_nl_policy, .maxattr = DEVLINK_ATTR_INDEX, .flags = GENL_CMD_CAP_DO, }, + { + .cmd = DEVLINK_CMD_RESOURCE_DUMP, + .dumpit = devlink_nl_resource_dump_dumpit, + .policy = devlink_resource_dump_dump_nl_policy, + .maxattr = DEVLINK_ATTR_INDEX, + .flags = GENL_CMD_CAP_DUMP, + }, { .cmd = DEVLINK_CMD_RELOAD, .validate = GENL_DONT_VALIDATE_STRICT,
net/devlink/netlink_gen.h +3 -1
@@ -18,7 +18,7 @@ extern const struct nla_policy devlink_dl_rate_tc_bws_nl_policy[DEVLINK_RATE_TC_extern const struct nla_policy devlink_dl_selftest_id_nl_policy[DEVLINK_ATTR_SELFTEST_ID_FLASH +1 ];/* Ops table for devlink */ -extern const struct genl_split_ops devlink_nl_ops[74 ]; +extern const struct genl_split_ops devlink_nl_ops[75 ];int devlink_nl_pre_doit (const struct genl_split_ops *ops,struct sk_buff *skb,struct genl_info *info);
@@ -80,6 +80,8 @@ int devlink_nl_dpipe_table_counters_set_doit(struct sk_buff *skb, struct genl_info *info);int devlink_nl_resource_set_doit (struct sk_buff *skb,struct genl_info *info);int devlink_nl_resource_dump_doit (struct sk_buff *skb,struct genl_info *info); +int devlink_nl_resource_dump_dumpit (struct sk_buff *skb, +struct netlink_callback *cb);int devlink_nl_reload_doit (struct sk_buff *skb,struct genl_info *info);int devlink_nl_param_get_doit (struct sk_buff *skb,struct genl_info *info); int devlink_nl_param_get_dumpit(struct sk_buff *skb,
net/devlink/resource.c +77 -0
89 lines not on this page · raw message
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 6/12 devlink: Include port resources in resource dump dumpit
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Allow querying devlink resources per-port via the resource-dump dumpit handler. Both device-level and all ports resources are included in the reply.
For example:
$ devlink resource show pci/0000:03:00.0: name local_max_SFs size 508 unit entry name external_max_SFs size 508 unit entry pci/0000:03:00.0/196608: name max_SFs size 20 unit entry pci/0000:03:00.1: name local_max_SFs size 508 unit entry name external_max_SFs size 508 unit entry pci/0000:03:00.1/262144: name max_SFs size 20 unit entry
--- net/devlink/devl_internal.h | 5 ++++ net/devlink/netlink.c | 2 ++ net/devlink/resource.c | 59 ++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 8 deletions(-)
net/devlink/devl_internal.h +5 -0
@@ -164,6 +164,11 @@ struct devlink_nl_dump_state {struct {u64 dump_ts; }; +/* DEVLINK_CMD_RESOURCE_DUMP */ +struct { +u32 index; +bool index_valid; + } port_ctx; }; };
net/devlink/netlink.c +2 -0
@@ -370,6 +370,8 @@ static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg,/* restart sub-object walk for the next instance */ state->idx =0 ; + state->port_ctx.index =0 ; + state->port_ctx.index_valid = false; }if (err != -EMSGSIZE )
net/devlink/resource.c +51 -8
88 lines not on this page · raw message
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 7/12 devlink: Add port-specific option to resource dump doit
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Allow querying devlink resources per-port via the resource-dump doit handler. When a port-index attribute is provided, only that port's resources are returned. When no port-index is given, only device-level resources are returned, preserving backward compatibility.
--- Documentation/netlink/specs/devlink.yaml | 4 +++- net/devlink/netlink_gen.c | 3 ++- net/devlink/netlink_gen.h | 4 ++-- net/devlink/resource.c | 20 +++++++++++++++++--- 4 files changed, 24 insertions(+), 7 deletions(-)
Documentation/netlink/specs/devlink.yaml +3 -1
@@ -1757,19 +1757,21 @@ operations: attribute-set: devlink dont-validate: [strict] do: - pre: devlink-nl-pre-doit + pre: devlink-nl-pre-doit-port-optional post: devlink-nl-post-doit request: attributes: - bus-name - dev-name - index + - port-index reply: &resource-dump-reply value: 36 attributes: - bus-name - dev-name - index + - port-index - resource-list dump: request:
net/devlink/netlink_gen.c +2 -1
@@ -309,6 +309,7 @@ static const struct nla_policy devlink_resource_dump_do_nl_policy[DEVLINK_ATTR_I [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, }, [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, }, [DEVLINK_ATTR_INDEX] = NLA_POLICY_FULL_RANGE(NLA_UINT, &devlink_attr_index_range), + [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, }, };/* DEVLINK_CMD_RESOURCE_DUMP - dump */
@@ -962,7 +963,7 @@ const struct genl_split_ops devlink_nl_ops[75] = { { .cmd = DEVLINK_CMD_RESOURCE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT, - .pre_doit = devlink_nl_pre_doit, + .pre_doit = devlink_nl_pre_doit_port_optional, .doit = devlink_nl_resource_dump_doit, .post_doit = devlink_nl_post_doit, .policy = devlink_resource_dump_do_nl_policy,
net/devlink/netlink_gen.h +2 -2
@@ -24,11 +24,11 @@ int devlink_nl_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb, struct genl_info *info);int devlink_nl_pre_doit_port (const struct genl_split_ops *ops,struct sk_buff *skb,struct genl_info *info); -int devlink_nl_pre_doit_dev_lock (const struct genl_split_ops *ops, -struct sk_buff *skb,struct genl_info *info);int devlink_nl_pre_doit_port_optional (const struct genl_split_ops *ops,struct sk_buff *skb,struct genl_info *info); +int devlink_nl_pre_doit_dev_lock (const struct genl_split_ops *ops, +struct sk_buff *skb,struct genl_info *info);void devlink_nl_post_doit (const struct genl_split_ops *ops,struct sk_buff *skb,struct genl_info *info);
net/devlink/resource.c +17 -3
@@ -251,8 +251,10 @@ static int devlink_resource_list_fill(struct sk_buff *skb,static int devlink_resource_fill (struct genl_info *info,enum devlink_command cmd,int flags) { +struct devlink_port *devlink_port = info->user_ptr[1 ];struct devlink *devlink = info->user_ptr[0 ];struct devlink_resource *resource; +struct list_head *resource_list;struct nlattr *resources_attr;struct sk_buff *skb =NULL ;struct nlmsghdr *nlh;
@@ -261,7 +263,9 @@ static int devlink_resource_fill(struct genl_info *info,int i;int err; - resource =list_first_entry (&devlink->resource_list, + resource_list = devlink_port ? + &devlink_port->resource_list : &devlink->resource_list; + resource =list_first_entry (resource_list, struct devlink_resource, list); start_again: err =devlink_nl_msg_reply_and_new (&skb, info);
@@ -277,6 +281,9 @@ static int devlink_resource_fill(struct genl_info *info,if (devlink_nl_put_handle (skb, devlink)) goto nla_put_failure; +if (devlink_port && +nla_put_u32 (skb,DEVLINK_ATTR_PORT_INDEX , devlink_port->index)) + goto nla_put_failure; resources_attr =nla_nest_start_noflag (skb,DEVLINK_ATTR_RESOURCE_LIST );
@@ -285,7 +292,7 @@ static int devlink_resource_fill(struct genl_info *info, incomplete = false; i =0 ; -list_for_each_entry_from (resource, &devlink->resource_list, list) { +list_for_each_entry_from (resource, resource_list, list) { err =devlink_resource_put (devlink, skb, resource);if (err) {if (!i)
@@ -319,9 +326,16 @@ static int devlink_resource_fill(struct genl_info *info,int devlink_nl_resource_dump_doit (struct sk_buff *skb,struct genl_info *info) { +struct devlink_port *devlink_port = info->user_ptr[1 ];struct devlink *devlink = info->user_ptr[0 ]; +struct list_head *resource_list; + +if (info->attrs[DEVLINK_ATTR_PORT_INDEX ] && !devlink_port) +return -ENODEV ; -if (list_empty (&devlink->resource_list)) + resource_list = devlink_port ? + &devlink_port->resource_list : &devlink->resource_list; +if (list_empty (resource_list))return -EOPNOTSUPP ;return devlink_resource_fill (info,DEVLINK_CMD_RESOURCE_DUMP ,0 );
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 8/12 selftest: netdevsim: Add devlink port resource doit test
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Tests that querying a specific port handle returns the expected resource name and size.
--- .../drivers/net/netdevsim/devlink.sh | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
tools/testing/selftests/drivers/net/netdevsim/devlink.sh +28 -1
@@ -5,7 +5,8 @@ lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS="fw_flash_test params_test \ params_default_test regions_test reload_test \ - netns_reload_test resource_test dev_info_test \ + netns_reload_test resource_test \ + port_resource_doit_test dev_info_test \ empty_reporter_test dummy_reporter_test rate_test" NUM_NETIFS=0 source $lib_dir/lib.sh
@@ -768,6 +769,32 @@ rate_node_del() devlink port function rate del $handle } +port_resource_doit_test() +{ + RET=0 + + local port_handle="${DL_HANDLE}/0" + local name + local size + + if ! devlink resource help 2>&1 | grep -q "PORT_INDEX"; then + echo "SKIP: devlink resource show with port not supported" + return + fi + + name=$(cmd_jq "devlink resource show $port_handle -j" \ + '.[][][].name') + [ "$name" == "test_resource" ] + check_err $? "wrong port resource name (got $name)" + + size=$(cmd_jq "devlink resource show $port_handle -j" \ + '.[][][].size') + [ "$size" == "20" ] + check_err $? "wrong port resource size (got $size)" + + log_test "port resource doit test" +} + rate_test() { RET=0
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 9/12 devlink: Document port-level resources and full dump
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Document the port-level resource support and the option to dump all resources, including both device-level and port-level entries.
--- .../networking/devlink/devlink-resource.rst | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+)
Documentation/networking/devlink/devlink-resource.rst +35 -0
@@ -74,3 +74,38 @@ attribute, which represents the pending change in size. For example: Note that changes in resource size may require a device reload to properly take effect. + +Port-level Resources and Full Dump +================================== + +In addition to device-level resources, ``devlink`` also supports port-level +resources. These resources are associated with a specific devlink port rather +than the device as a whole. + +To list resources for all devlink devices and ports: + +.. code:: shell + + $ devlink resource show + pci/0000:03:00.0: + name max_local_SFs size 128 unit entry dpipe_tables none + name max_external_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.0/196608: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.0/196609: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1: + name max_local_SFs size 128 unit entry dpipe_tables none + name max_external_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1/196708: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1/196709: + name max_SFs size 128 unit entry dpipe_tables none + +To show resources for a specific port: + +.. code:: shell + + $ devlink resource show pci/0000:03:00.0/196608 + pci/0000:03:00.0/196608: + name max_SFs size 128 unit entry dpipe_tables none
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 10/12 devlink: Add resource scope filtering to resource dump
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Allow filtering the resource dump to device-level or port-level resources using the 'scope' option.
Example - dump only device-level resources:
$ devlink resource show scope dev
pci/0000:03:00.0:
name max_local_SFs size 128 unit entry dpipe_tables none
name max_external_SFs size 128 unit entry dpipe_tables none
pci/0000:03:00.1:
name max_local_SFs size 128 unit entry dpipe_tables none
name max_external_SFs size 128 unit entry dpipe_tables noneExample - dump only port-level resources:
$ devlink resource show scope port
pci/0000:03:00.0/196608:
name max_SFs size 128 unit entry dpipe_tables none
pci/0000:03:00.0/196609:
name max_SFs size 128 unit entry dpipe_tables none
pci/0000:03:00.1/196708:
name max_SFs size 128 unit entry dpipe_tables none
pci/0000:03:00.1/196709:
name max_SFs size 128 unit entry dpipe_tables none--- Documentation/netlink/specs/devlink.yaml | 24 +++++++++++++++++++++++- include/uapi/linux/devlink.h | 11 +++++++++++ net/devlink/netlink_gen.c | 5 +++-- net/devlink/resource.c | 19 ++++++++++++++++++- 4 files changed, 55 insertions(+), 4 deletions(-)
Documentation/netlink/specs/devlink.yaml +23 -1
@@ -157,6 +157,14 @@ definitions: entries: - name: entry + - + type: enum + name: resource-scope + entries: + - + name: dev + - + name: port - type: enum name: reload-action
@@ -873,6 +881,16 @@ attribute-sets: doc: Unique devlink instance index. checks: max: u32-max + - + name: resource-scope-mask + type: u32 + enum: resource-scope + enum-as-flags: true + doc: | + Bitmask selecting which resource classes to include in a + resource-dump response. Bit 0 (dev) selects device-level + resources; bit 1 (port) selects port-level resources. + When absent all classes are returned. - name: dl-dev-stats subset-of: devlink
@@ -1775,7 +1793,11 @@ operations: - resource-list dump: request: - attributes: *dev-id-attrs + attributes: + - bus-name + - dev-name + - index + - resource-scope-mask reply: *resource-dump-reply -
include/uapi/linux/devlink.h +11 -0
@@ -645,6 +645,7 @@ enum devlink_attr {DEVLINK_ATTR_PARAM_RESET_DEFAULT ,/* flag */ DEVLINK_ATTR_INDEX ,/* uint */ + DEVLINK_ATTR_RESOURCE_SCOPE_MASK, /* u32 *//* Add new attributes above here, update the spec in * Documentation/netlink/specs/devlink.yaml and re-generate
@@ -704,6 +705,16 @@ enum devlink_resource_unit { DEVLINK_RESOURCE_UNIT_ENTRY, }; +enum devlink_resource_scope { +DEVLINK_RESOURCE_SCOPE_DEV_BIT , +DEVLINK_RESOURCE_SCOPE_PORT_BIT , +}; + +#define DEVLINK_RESOURCE_SCOPE_DEV \ + _BITUL(DEVLINK_RESOURCE_SCOPE_DEV_BIT) +#define DEVLINK_RESOURCE_SCOPE_PORT \ + _BITUL(DEVLINK_RESOURCE_SCOPE_PORT_BIT) +enum devlink_port_fn_attr_cap {DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT ,DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT ,
net/devlink/netlink_gen.c +3 -2
@@ -313,10 +313,11 @@ static const struct nla_policy devlink_resource_dump_do_nl_policy[DEVLINK_ATTR_I };/* DEVLINK_CMD_RESOURCE_DUMP - dump */ -static const struct nla_policy devlink_resource_dump_dump_nl_policy[DEVLINK_ATTR_INDEX +1 ] = { +static const struct nla_policy devlink_resource_dump_dump_nl_policy[DEVLINK_ATTR_RESOURCE_SCOPE_MASK +1 ] = { [DEVLINK_ATTR_BUS_NAME ] = { .type =NLA_NUL_STRING , }, [DEVLINK_ATTR_DEV_NAME ] = { .type =NLA_NUL_STRING , }, [DEVLINK_ATTR_INDEX ] =NLA_POLICY_FULL_RANGE (NLA_UINT , &devlink_attr_index_range), + [DEVLINK_ATTR_RESOURCE_SCOPE_MASK ] =NLA_POLICY_MASK (NLA_U32 ,0x3 ), };/* DEVLINK_CMD_RELOAD - do */
@@ -974,7 +975,7 @@ const struct genl_split_ops devlink_nl_ops[75] = { .cmd = DEVLINK_CMD_RESOURCE_DUMP, .dumpit = devlink_nl_resource_dump_dumpit, .policy = devlink_resource_dump_dump_nl_policy, - .maxattr = DEVLINK_ATTR_INDEX, + .maxattr = DEVLINK_ATTR_RESOURCE_SCOPE_MASK, .flags = GENL_CMD_CAP_DUMP, }, {
net/devlink/resource.c +18 -1
@@ -398,11 +398,25 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, struct netlink_callback *cb, int flags) {struct devlink_nl_dump_state *state =devlink_dump_state (cb); +const struct genl_info *info =genl_info_dump (cb);struct devlink_port *devlink_port; +struct nlattr *scope_attr =NULL ;unsigned long port_idx; +u32 scope =0 ;int err; -if (!state->port_ctx.index_valid) { +if (info->attrs && info->attrs[DEVLINK_ATTR_RESOURCE_SCOPE_MASK ]) { + scope_attr = info->attrs[DEVLINK_ATTR_RESOURCE_SCOPE_MASK ]; + scope =nla_get_u32 (scope_attr); +if (!scope) { +NL_SET_ERR_MSG_ATTR (info->extack, scope_attr, +"empty resource scope selection" ); +return -EINVAL ; + } + } + +if (!state->port_ctx.index_valid && + (!scope || (scope &DEVLINK_RESOURCE_SCOPE_DEV ))) { err =devlink_resource_dump_fill_one (skb, devlink,NULL , cb, flags, &state->idx);if (err)
@@ -410,6 +424,8 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, state->idx =0 ; } +if (scope && !(scope &DEVLINK_RESOURCE_SCOPE_PORT )) + goto out;/* Check in case port was removed between dump callbacks. */ if (state->port_ctx.index_valid && !xa_load (&devlink->ports, state->port_ctx.index))
@@ -425,6 +441,7 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, } state->idx =0 ; } +out: state->port_ctx.index_valid = false; state->port_ctx.index =0 ;return 0 ;
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 11/12 selftest: netdevsim: Add resource dump and scope filter test
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Add resource_dump_test() which verifies dumping resources for all devices and ports, and tests that scope=dev returns only device-level resources and scope=port returns only port resources.
Skip if userspace does not support the scope parameter.
--- .../drivers/net/netdevsim/devlink.sh | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-)
tools/testing/selftests/drivers/net/netdevsim/devlink.sh +51 -1
@@ -5,7 +5,7 @@ lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS="fw_flash_test params_test \ params_default_test regions_test reload_test \ - netns_reload_test resource_test \ + netns_reload_test resource_test resource_dump_test \ port_resource_doit_test dev_info_test \ empty_reporter_test dummy_reporter_test rate_test" NUM_NETIFS=0
@@ -483,6 +483,56 @@ resource_test() log_test "resource test" } +resource_dump_test() +{ + RET=0 + + local port_jq + local dev_jq + local dl_jq + local count + + dl_jq="with_entries(select(.key | startswith(\"$DL_HANDLE\")))" + port_jq="[.[] | $dl_jq | keys |" + port_jq+=" map(select(test(\"/.+/\"))) | length] | add" + dev_jq="[.[] | $dl_jq | keys |" + dev_jq+=" map(select(test(\"/.+/\")|not)) | length] | add" + + if ! devlink resource help 2>&1 | grep -q "scope"; then + echo "SKIP: devlink resource show not supported" + return + fi + + devlink resource show > /dev/null 2>&1 + check_err $? "Failed to dump all resources" + + count=$(cmd_jq "devlink resource show -j" "$port_jq") + [ "$count" -gt "0" ] + check_err $? "missing port resources in resource dump" + + count=$(cmd_jq "devlink resource show -j" "$dev_jq") + [ "$count" -gt "0" ] + check_err $? "missing device resources in resource dump" + + count=$(cmd_jq "devlink resource show scope dev -j" "$dev_jq") + [ "$count" -gt "0" ] + check_err $? "dev scope missing device resources" + + count=$(cmd_jq "devlink resource show scope dev -j" "$port_jq") + [ "$count" -eq "0" ] + check_err $? "dev scope returned port resources" + + count=$(cmd_jq "devlink resource show scope port -j" "$port_jq") + [ "$count" -gt "0" ] + check_err $? "port scope missing port resources" + + count=$(cmd_jq "devlink resource show scope port -j" "$dev_jq") + [ "$count" -eq "0" ] + check_err $? "port scope returned device resources" + + log_test "resource dump test" +} + info_get() { local name=$1
Signature · 1 line
2.44.0
Tariq Toukan
maintainerPATCH v5 12/12 devlink: Document resource scope filtering
In reply to Tariq ToukanFrom: Or Har-Toov <[email protected]>
Document the scope parameter for devlink resource show, which allows filtering the dump to device-level or port-level resources only.
--- .../networking/devlink/devlink-resource.rst | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+)
Documentation/networking/devlink/devlink-resource.rst +35 -0
@@ -109,3 +109,38 @@ To show resources for a specific port: $ devlink resource show pci/0000:03:00.0/196608 pci/0000:03:00.0/196608: name max_SFs size 128 unit entry dpipe_tables none + +Resource Scope Filtering +======================== + +When dumping resources for all devices, ``devlink resource show`` accepts +an optional ``scope`` parameter to restrict the response to device-level +resources, port-level resources, or both (the default). + +To dump only device-level resources across all devices: + +.. code:: shell + + $ devlink resource show scope dev + pci/0000:03:00.0: + name max_local_SFs size 128 unit entry dpipe_tables none + name max_external_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1: + name max_local_SFs size 128 unit entry dpipe_tables none + name max_external_SFs size 128 unit entry dpipe_tables none + +To dump only port-level resources across all devices: + +.. code:: shell + + $ devlink resource show scope port + pci/0000:03:00.0/196608: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.0/196609: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1/196708: + name max_SFs size 128 unit entry dpipe_tables none + pci/0000:03:00.1/196709: + name max_SFs size 128 unit entry dpipe_tables none + +Note that port-level resources are read-only.
Signature · 1 line
2.44.0
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Hello:
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:
Quoted 9 lines · On Tue, 7 Apr 2026 22:40:55 +0300 you wrote:
Hi,
This series by Or adds devlink per-port resource support. See detailed description by Or below [1].
Regards,
Tariq[...]
Here is the summary with links:
- [net-next,V5,01/12] devlink: Refactor resource functions to be generic
https://git.kernel.org/netdev/net-next/c/7be3163c49b2 - [net-next,V5,02/12] devlink: Add port-level resource registration infrastructure https://git.kernel.org/netdev/net-next/c/6f38acfed5ed - [net-next,V5,03/12] net/mlx5: Register SF resource on PF port representor https://git.kernel.org/netdev/net-next/c/4be8326d817e - [net-next,V5,04/12] netdevsim: Add devlink port resource registration https://git.kernel.org/netdev/net-next/c/085b234b28cc - [net-next,V5,05/12] devlink: Add dump support for device-level resources https://git.kernel.org/netdev/net-next/c/11636b550eea - [net-next,V5,06/12] devlink: Include port resources in resource dump dumpit https://git.kernel.org/netdev/net-next/c/810b76394d69 - [net-next,V5,07/12] devlink: Add port-specific option to resource dump doit https://git.kernel.org/netdev/net-next/c/7511ff14f30d - [net-next,V5,08/12] selftest: netdevsim: Add devlink port resource doit test https://git.kernel.org/netdev/net-next/c/396135377104 - [net-next,V5,09/12] devlink: Document port-level resources and full dump https://git.kernel.org/netdev/net-next/c/170e160a0e7c - [net-next,V5,10/12] devlink: Add resource scope filtering to resource dump https://git.kernel.org/netdev/net-next/c/1bc45341a6ea - [net-next,V5,11/12] selftest: netdevsim: Add resource dump and scope filter test https://git.kernel.org/netdev/net-next/c/2a8e91235254 - [net-next,V5,12/12] devlink: Document resource scope filtering https://git.kernel.org/netdev/net-next/c/78c327c1728d
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
Jakub Kicinski
maintainerQuoted 2 lines · On Tue, 7 Apr 2026 22:40:55 +0300 Tariq Toukan wrote:
Userspace patches for iproute2:
https://github.com/ohartoov/iproute2/tree/port_resources
Hi! As far as I can tell these iproute2 patches have not even been posted? Please try to get them upstream ASAP, we have to manually carry them in the CI right now.