public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] devlink: add per-port resource support
@ 2026-02-03  7:10 Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko

Hi,

This series 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 adds devlink core infrastructure for per-port resources
Patch #2 registers SF resource on PF port representor in mlx5
         support dump
Patch #3 adds port resource registration to netdevsim for testing
Patch #4 adds selftest for devlink port resources
Patch #5 adds documentation for port-level resources

With this series (and upcoming userspace patches), users can query
per-port resources:

$ devlink port resource show pci/0000:03:00.0/196608
pci/0000:03:00.0/196608:
  name max_SFs size 20 unit entry

$ devlink port resource show
pci/0000:03:00.0/196608:
  name max_SFs size 20 unit entry
pci/0000:03:00.1/262144:
  name max_SFs size 20 unit entry

Or Har-Toov (5):
  devlink: Add port-level resource infrastructure
  net/mlx5: Register SF resource on PF port representor
  netdevsim: Add devlink port resource registration
  selftest: netdevsim: Add devlink port resource test
  devlink: Document port-level resources

 Documentation/netlink/specs/devlink.yaml      |  23 ++
 .../networking/devlink/devlink-resource.rst   |  36 +++
 .../net/ethernet/mellanox/mlx5/core/devlink.h |   4 +
 .../mellanox/mlx5/core/esw/devlink_port.c     |  37 +++
 drivers/net/netdevsim/dev.c                   |  22 +-
 drivers/net/netdevsim/netdevsim.h             |   4 +
 include/net/devlink.h                         |   8 +
 include/uapi/linux/devlink.h                  |   2 +
 net/devlink/netlink.c                         |   2 +-
 net/devlink/netlink_gen.c                     |  32 +-
 net/devlink/netlink_gen.h                     |   6 +-
 net/devlink/port.c                            |   3 +
 net/devlink/resource.c                        | 282 ++++++++++++++----
 .../drivers/net/netdevsim/devlink.sh          |  32 +-
 14 files changed, 434 insertions(+), 59 deletions(-)


base-commit: a22f57757f7e88c890499265c383ecb32900b645
-- 
2.40.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net-next 1/5] devlink: Add port-level resource infrastructure
  2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
@ 2026-02-03  7:10 ` Tariq Toukan
  2026-02-04  9:51   ` Jiri Pirko
  2026-02-04  9:58   ` Jiri Pirko
  2026-02-03  7:10 ` [PATCH net-next 2/5] net/mlx5: Register SF resource on PF port representor Tariq Toukan
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

From: Or Har-Toov <ohartoov@nvidia.com>

The current devlink resource infrastructure only supports 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 and querying resources at the port level,
allowing drivers to expose per-port resource limits and usage.

Example output:

  $ devlink port resource show
  pci/0000:03:00.0/196608:
    name max_SFs size 20 unit entry
  pci/0000:03:00.1/262144:
    name max_SFs size 20 unit entry

  $ devlink port resource show pci/0000:03:00.0/196608
  pci/0000:03:00.0/196608:
    name max_SFs size 20 unit entry

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 Documentation/netlink/specs/devlink.yaml |  23 ++
 include/net/devlink.h                    |   8 +
 include/uapi/linux/devlink.h             |   2 +
 net/devlink/netlink.c                    |   2 +-
 net/devlink/netlink_gen.c                |  32 ++-
 net/devlink/netlink_gen.h                |   6 +-
 net/devlink/port.c                       |   3 +
 net/devlink/resource.c                   | 282 ++++++++++++++++++-----
 8 files changed, 301 insertions(+), 57 deletions(-)

diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
index 837112da6738..0290db1b8393 100644
--- a/Documentation/netlink/specs/devlink.yaml
+++ b/Documentation/netlink/specs/devlink.yaml
@@ -2336,3 +2336,26 @@ operations:
             - bus-name
             - dev-name
             - port-index
+
+    -
+      name: port-resource-get
+      doc: Get port resources.
+      attribute-set: devlink
+      dont-validate: [strict]
+      do:
+        pre: devlink-nl-pre-doit-port
+        post: devlink-nl-post-doit
+        request:
+          value: 85
+          attributes: *port-id-attrs
+        reply: &port-resource-get-reply
+          value: 85
+          attributes:
+            - bus-name
+            - dev-name
+            - port-index
+            - resource-list
+      dump:
+        request:
+          attributes: *dev-id-attrs
+        reply: *port-resource-get-reply
diff --git a/include/net/devlink.h b/include/net/devlink.h
index cb839e0435a1..40335ecc3343 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -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;
@@ -1881,6 +1882,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);
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index e7d6b6d13470..74a541013af6 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -141,6 +141,8 @@ enum devlink_command {
 
 	DEVLINK_CMD_NOTIFY_FILTER_SET,
 
+	DEVLINK_CMD_PORT_RESOURCE_GET,	/* can dump */
+
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 593605c1b1ef..c78c31779622 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -367,7 +367,7 @@ struct genl_family devlink_nl_family __ro_after_init = {
 	.module		= THIS_MODULE,
 	.split_ops	= devlink_nl_ops,
 	.n_split_ops	= ARRAY_SIZE(devlink_nl_ops),
-	.resv_start_op	= DEVLINK_CMD_SELFTESTS_RUN + 1,
+	.resv_start_op	= DEVLINK_CMD_PORT_RESOURCE_GET + 1,
 	.mcgrps		= devlink_nl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
 	.sock_priv_size		= sizeof(struct devlink_nl_sock_priv),
diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c
index f4c61c2b4f22..692d7862183a 100644
--- a/net/devlink/netlink_gen.c
+++ b/net/devlink/netlink_gen.c
@@ -604,8 +604,21 @@ static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_
 	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
 };
 
+/* DEVLINK_CMD_PORT_RESOURCE_GET - do */
+static const struct nla_policy devlink_port_resource_get_do_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
+	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
+};
+
+/* DEVLINK_CMD_PORT_RESOURCE_GET - dump */
+static const struct nla_policy devlink_port_resource_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
+	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+};
+
 /* Ops table for devlink */
-const struct genl_split_ops devlink_nl_ops[74] = {
+const struct genl_split_ops devlink_nl_ops[76] = {
 	{
 		.cmd		= DEVLINK_CMD_GET,
 		.validate	= GENL_DONT_VALIDATE_STRICT,
@@ -1284,4 +1297,21 @@ const struct genl_split_ops devlink_nl_ops[74] = {
 		.maxattr	= DEVLINK_ATTR_PORT_INDEX,
 		.flags		= GENL_CMD_CAP_DO,
 	},
+	{
+		.cmd		= DEVLINK_CMD_PORT_RESOURCE_GET,
+		.validate	= GENL_DONT_VALIDATE_STRICT,
+		.pre_doit	= devlink_nl_pre_doit_port,
+		.doit		= devlink_nl_port_resource_get_doit,
+		.post_doit	= devlink_nl_post_doit,
+		.policy		= devlink_port_resource_get_do_nl_policy,
+		.maxattr	= DEVLINK_ATTR_PORT_INDEX,
+		.flags		= GENL_CMD_CAP_DO,
+	},
+	{
+		.cmd		= DEVLINK_CMD_PORT_RESOURCE_GET,
+		.dumpit		= devlink_nl_port_resource_get_dumpit,
+		.policy		= devlink_port_resource_get_dump_nl_policy,
+		.maxattr	= DEVLINK_ATTR_DEV_NAME,
+		.flags		= GENL_CMD_CAP_DUMP,
+	},
 };
diff --git a/net/devlink/netlink_gen.h b/net/devlink/netlink_gen.h
index 2817d53a0eba..204a665d2fd2 100644
--- a/net/devlink/netlink_gen.h
+++ b/net/devlink/netlink_gen.h
@@ -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[76];
 
 int devlink_nl_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
 			struct genl_info *info);
@@ -146,5 +146,9 @@ int devlink_nl_selftests_get_dumpit(struct sk_buff *skb,
 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info);
 int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
 				      struct genl_info *info);
+int devlink_nl_port_resource_get_doit(struct sk_buff *skb,
+				      struct genl_info *info);
+int devlink_nl_port_resource_get_dumpit(struct sk_buff *skb,
+					struct netlink_callback *cb);
 
 #endif /* _LINUX_DEVLINK_GEN_H */
diff --git a/net/devlink/port.c b/net/devlink/port.c
index 93d8a25bb920..10d0d88894a3 100644
--- a/net/devlink/port.c
+++ b/net/devlink/port.c
@@ -1024,6 +1024,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);
@@ -1041,6 +1042,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);
 
@@ -1135,6 +1137,7 @@ void devl_port_unregister(struct devlink_port *devlink_port)
 	devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
 	xa_erase(&devlink_port->devlink->ports, devlink_port->index);
 	WARN_ON(!list_empty(&devlink_port->reporter_list));
+	devlink_port_fini(devlink_port);
 	devlink_port->registered = false;
 }
 EXPORT_SYMBOL_GPL(devl_port_unregister);
diff --git a/net/devlink/resource.c b/net/devlink/resource.c
index 2d6324f3d91f..1c563c76ddb6 100644
--- a/net/devlink/resource.c
+++ b/net/devlink/resource.c
@@ -36,15 +36,16 @@ struct devlink_resource {
 };
 
 static struct devlink_resource *
-devlink_resource_find(struct devlink *devlink,
-		      struct devlink_resource *resource, u64 resource_id)
+devlink_resource_find_by_list(struct list_head *res_list_head,
+			      struct devlink_resource *resource,
+			      u64 resource_id)
 {
 	struct list_head *resource_list;
 
 	if (resource)
 		resource_list = &resource->resource_list;
 	else
-		resource_list = &devlink->resource_list;
+		resource_list = res_list_head;
 
 	list_for_each_entry(resource, resource_list, list) {
 		struct devlink_resource *child_resource;
@@ -52,14 +53,23 @@ devlink_resource_find(struct devlink *devlink,
 		if (resource->id == resource_id)
 			return resource;
 
-		child_resource = devlink_resource_find(devlink, resource,
-						       resource_id);
+		child_resource = devlink_resource_find_by_list(res_list_head,
+							       resource,
+							       resource_id);
 		if (child_resource)
 			return child_resource;
 	}
 	return NULL;
 }
 
+static struct devlink_resource *
+devlink_resource_find(struct devlink *devlink,
+		      struct devlink_resource *resource, u64 resource_id)
+{
+	return devlink_resource_find_by_list(&devlink->resource_list,
+					     resource, resource_id);
+}
+
 static void
 devlink_resource_validate_children(struct devlink_resource *resource)
 {
@@ -214,8 +224,10 @@ static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
 }
 
 static int devlink_resource_fill(struct genl_info *info,
+				 struct list_head *resource_list,
 				 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 nlattr *resources_attr;
@@ -226,8 +238,11 @@ static int devlink_resource_fill(struct genl_info *info,
 	int i;
 	int err;
 
-	resource = list_first_entry(&devlink->resource_list,
-				    struct devlink_resource, list);
+	if (list_empty(resource_list))
+		return -EOPNOTSUPP;
+
+	resource = list_first_entry(resource_list, struct devlink_resource,
+				    list);
 start_again:
 	err = devlink_nl_msg_reply_and_new(&skb, info);
 	if (err)
@@ -243,6 +258,10 @@ 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);
 	if (!resources_attr)
@@ -250,7 +269,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)
@@ -286,10 +305,8 @@ int devlink_nl_resource_dump_doit(struct sk_buff *skb, struct genl_info *info)
 {
 	struct devlink *devlink = info->user_ptr[0];
 
-	if (list_empty(&devlink->resource_list))
-		return -EOPNOTSUPP;
-
-	return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
+	return devlink_resource_fill(info, &devlink->resource_list,
+				     DEVLINK_CMD_RESOURCE_DUMP, 0);
 }
 
 int devlink_resources_validate(struct devlink *devlink,
@@ -314,26 +331,12 @@ int devlink_resources_validate(struct devlink *devlink,
 	return err;
 }
 
-/**
- * devl_resource_register - devlink resource register
- *
- * @devlink: devlink
- * @resource_name: resource's name
- * @resource_size: resource's size
- * @resource_id: resource's id
- * @parent_resource_id: resource's parent id
- * @size_params: size parameters
- *
- * Generic resources should reuse the same names across drivers.
- * Please see the generic resources list at:
- * Documentation/networking/devlink/devlink-resource.rst
- */
-int devl_resource_register(struct devlink *devlink,
-			   const char *resource_name,
-			   u64 resource_size,
-			   u64 resource_id,
-			   u64 parent_resource_id,
-			   const struct devlink_resource_size_params *size_params)
+static int
+devl_resource_reg_by_list(struct devlink *devlink,
+			  struct list_head *res_list_head,
+			  const char *resource_name, u64 resource_size,
+			  u64 resource_id, u64 parent_res_id,
+			  const struct devlink_resource_size_params *params)
 {
 	struct devlink_resource *resource;
 	struct list_head *resource_list;
@@ -341,9 +344,10 @@ int devl_resource_register(struct devlink *devlink,
 
 	lockdep_assert_held(&devlink->lock);
 
-	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
+	top_hierarchy = parent_res_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
 
-	resource = devlink_resource_find(devlink, NULL, resource_id);
+	resource = devlink_resource_find_by_list(res_list_head, NULL,
+						 resource_id);
 	if (resource)
 		return -EEXIST;
 
@@ -352,15 +356,15 @@ int devl_resource_register(struct devlink *devlink,
 		return -ENOMEM;
 
 	if (top_hierarchy) {
-		resource_list = &devlink->resource_list;
+		resource_list = res_list_head;
 	} else {
-		struct devlink_resource *parent_resource;
+		struct devlink_resource *parent_res;
 
-		parent_resource = devlink_resource_find(devlink, NULL,
-							parent_resource_id);
-		if (parent_resource) {
-			resource_list = &parent_resource->resource_list;
-			resource->parent = parent_resource;
+		parent_res = devlink_resource_find_by_list(res_list_head, NULL,
+							   parent_res_id);
+		if (parent_res) {
+			resource_list = &parent_res->resource_list;
+			resource->parent = parent_res;
 		} else {
 			kfree(resource);
 			return -EINVAL;
@@ -372,46 +376,78 @@ int devl_resource_register(struct devlink *devlink,
 	resource->size_new = resource_size;
 	resource->id = resource_id;
 	resource->size_valid = true;
-	memcpy(&resource->size_params, size_params,
-	       sizeof(resource->size_params));
+	memcpy(&resource->size_params, params, sizeof(resource->size_params));
 	INIT_LIST_HEAD(&resource->resource_list);
 	list_add_tail(&resource->list, resource_list);
 
 	return 0;
 }
+
+/**
+ * devl_resource_register - devlink resource register
+ *
+ * @devlink: devlink
+ * @resource_name: resource's name
+ * @resource_size: resource's size
+ * @resource_id: resource's id
+ * @parent_resource_id: resource's parent id
+ * @params: size parameters
+ *
+ * Generic resources should reuse the same names across drivers.
+ * Please see the generic resources list at:
+ * Documentation/networking/devlink/devlink-resource.rst
+ *
+ * Return: 0 on success, negative error code otherwise.
+ */
+int devl_resource_register(struct devlink *devlink, const char *resource_name,
+			   u64 resource_size, u64 resource_id,
+			   u64 parent_resource_id,
+			   const struct devlink_resource_size_params *params)
+{
+	return devl_resource_reg_by_list(devlink, &devlink->resource_list,
+					      resource_name, resource_size,
+					      resource_id, parent_resource_id,
+					      params);
+}
 EXPORT_SYMBOL_GPL(devl_resource_register);
 
-static void devlink_resource_unregister(struct devlink *devlink,
-					struct devlink_resource *resource)
+static void devlink_resource_unregister(struct devlink_resource *resource)
 {
 	struct devlink_resource *tmp, *child_resource;
 
 	list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
 				 list) {
-		devlink_resource_unregister(devlink, child_resource);
+		devlink_resource_unregister(child_resource);
 		list_del(&child_resource->list);
 		kfree(child_resource);
 	}
 }
 
-/**
- * devl_resources_unregister - free all resources
- *
- * @devlink: devlink
- */
-void devl_resources_unregister(struct devlink *devlink)
+static void
+devl_resources_unregister_by_list(struct devlink *devlink,
+				  struct list_head *res_list_head)
 {
 	struct devlink_resource *tmp, *child_resource;
 
 	lockdep_assert_held(&devlink->lock);
 
-	list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
+	list_for_each_entry_safe(child_resource, tmp, res_list_head,
 				 list) {
-		devlink_resource_unregister(devlink, child_resource);
+		devlink_resource_unregister(child_resource);
 		list_del(&child_resource->list);
 		kfree(child_resource);
 	}
 }
+
+/**
+ * devl_resources_unregister - free all resources
+ *
+ * @devlink: devlink
+ */
+void devl_resources_unregister(struct devlink *devlink)
+{
+	devl_resources_unregister_by_list(devlink, &devlink->resource_list);
+}
 EXPORT_SYMBOL_GPL(devl_resources_unregister);
 
 /**
@@ -502,3 +538,141 @@ void devl_resource_occ_get_unregister(struct devlink *devlink,
 	resource->occ_get_priv = NULL;
 }
 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
+
+/**
+ * devl_port_resource_register - devlink port resource register
+ *
+ * @devlink_port: devlink port
+ * @resource_name: resource's name
+ * @resource_size: resource's size
+ * @resource_id: resource's id
+ * @parent_resource_id: resource's parent id
+ * @params: size parameters for the resource
+ *
+ * Generic resources should reuse the same names across drivers.
+ * Please see the generic resources list at:
+ * Documentation/networking/devlink/devlink-resource.rst
+ *
+ * Return: 0 on success, negative error code otherwise.
+ */
+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)
+{
+	return devl_resource_reg_by_list(devlink_port->devlink,
+					 &devlink_port->resource_list,
+					 resource_name, resource_size,
+					 resource_id, parent_resource_id,
+					 params);
+}
+EXPORT_SYMBOL_GPL(devl_port_resource_register);
+
+/**
+ * devl_port_resources_unregister - unregister all devlink port resources
+ *
+ * @devlink_port: devlink port
+ */
+void devl_port_resources_unregister(struct devlink_port *devlink_port)
+{
+	devl_resources_unregister_by_list(devlink_port->devlink,
+					  &devlink_port->resource_list);
+}
+EXPORT_SYMBOL_GPL(devl_port_resources_unregister);
+
+static int devlink_nl_port_resource_fill(struct sk_buff *msg,
+					 struct devlink_port *devlink_port,
+					 enum devlink_command cmd,
+					 u32 portid, u32 seq, int flags)
+{
+	struct devlink *devlink = devlink_port->devlink;
+	struct devlink_resource *resource;
+	struct nlattr *resources_attr;
+	void *hdr;
+
+	if (list_empty(&devlink_port->resource_list))
+		return 0;
+
+	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (devlink_nl_put_handle(msg, devlink))
+		goto nla_put_failure;
+	if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
+		goto nla_put_failure;
+
+	resources_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_RESOURCE_LIST);
+	if (!resources_attr)
+		goto nla_put_failure;
+
+	list_for_each_entry(resource, &devlink_port->resource_list, list) {
+		if (devlink_resource_put(devlink, msg, resource)) {
+			nla_nest_cancel(msg, resources_attr);
+			goto nla_put_failure;
+		}
+	}
+	nla_nest_end(msg, resources_attr);
+	genlmsg_end(msg, hdr);
+	return 0;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
+}
+
+int devlink_nl_port_resource_get_doit(struct sk_buff *skb,
+				      struct genl_info *info)
+{
+	struct devlink_port *devlink_port = info->user_ptr[1];
+	struct sk_buff *msg;
+	int err;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	err = devlink_nl_port_resource_fill(msg, devlink_port,
+					    DEVLINK_CMD_PORT_RESOURCE_GET,
+					    info->snd_portid, info->snd_seq, 0);
+	if (err) {
+		nlmsg_free(msg);
+		return err;
+	}
+
+	return genlmsg_reply(msg, info);
+}
+
+static int
+devlink_nl_port_resource_get_dump_one(struct sk_buff *msg,
+				      struct devlink *devlink,
+				      struct netlink_callback *cb, int flags)
+{
+	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
+	u32 cmd = DEVLINK_CMD_PORT_RESOURCE_GET;
+	struct devlink_port *devlink_port;
+	unsigned long port_index;
+	int err;
+
+	xa_for_each_start(&devlink->ports, port_index, devlink_port,
+			  state->idx) {
+		err = devlink_nl_port_resource_fill(msg, devlink_port, cmd,
+						    NETLINK_CB(cb->skb).portid,
+						    cb->nlh->nlmsg_seq, flags);
+		if (err) {
+			state->idx = port_index;
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+int devlink_nl_port_resource_get_dumpit(struct sk_buff *skb,
+					struct netlink_callback *cb)
+{
+	return devlink_nl_dumpit(skb, cb,
+				 devlink_nl_port_resource_get_dump_one);
+}
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 2/5] net/mlx5: Register SF resource on PF port representor
  2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
@ 2026-02-03  7:10 ` Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 3/5] netdevsim: Add devlink port resource registration Tariq Toukan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

From: Or Har-Toov <ohartoov@nvidia.com>

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 port resource show
  pci/0000:03:00.0/196608:
    name max_SFs size 20 unit entry
  pci/0000:03:00.1/262144:
    name max_SFs size 20 unit entry

  $ devlink port 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 120

We can create up to 20 SFs over devlink port pci/0000:03:00.0/196608,
with pfnum 0 and controller 1.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../net/ethernet/mellanox/mlx5/core/devlink.h |  4 ++
 .../mellanox/mlx5/core/esw/devlink_port.c     | 37 +++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
index 43b9bf8829cf..4fbb3926a3e5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.h
@@ -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,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
index 89a58dee50b3..2b6c3c9e5cc3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
@@ -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)
@@ -156,6 +157,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;
@@ -187,6 +214,15 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlx
 	if (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:
@@ -201,6 +237,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);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 3/5] netdevsim: Add devlink port resource registration
  2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 2/5] net/mlx5: Register SF resource on PF port representor Tariq Toukan
@ 2026-02-03  7:10 ` Tariq Toukan
  2026-02-04  9:54   ` Jiri Pirko
  2026-02-03  7:10 ` [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test Tariq Toukan
  2026-02-03  7:10 ` [PATCH net-next 5/5] devlink: Document port-level resources Tariq Toukan
  4 siblings, 1 reply; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

From: Or Har-Toov <ohartoov@nvidia.com>

Register port-level resources for netdevsim ports to enable testing
of the port resource infrastructure.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 drivers/net/netdevsim/dev.c       | 22 +++++++++++++++++++++-
 drivers/net/netdevsim/netdevsim.h |  4 ++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index dfd571b22107..ebda1b961664 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -1486,9 +1486,24 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ
 	if (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, "max_sfs", 20,
+						  NSIM_PORT_RESOURCE_MAX_SFS,
+						  parent_id, &params);
+		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 +1526,9 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ
 	nsim_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 +1545,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);
 }
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index f767fc8a7505..11ea1a52924a 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -224,6 +224,10 @@ enum nsim_resource_id {
 	NSIM_RESOURCE_NEXTHOPS,
 };
 
+enum nsim_port_resource_id {
+	NSIM_PORT_RESOURCE_MAX_SFS = 1,
+};
+
 struct nsim_dev_health {
 	struct devlink_health_reporter *empty_reporter;
 	struct devlink_health_reporter *dummy_reporter;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test
  2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
                   ` (2 preceding siblings ...)
  2026-02-03  7:10 ` [PATCH net-next 3/5] netdevsim: Add devlink port resource registration Tariq Toukan
@ 2026-02-03  7:10 ` Tariq Toukan
  2026-02-03 10:16   ` Paolo Abeni
  2026-02-03  7:10 ` [PATCH net-next 5/5] devlink: Document port-level resources Tariq Toukan
  4 siblings, 1 reply; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

From: Or Har-Toov <ohartoov@nvidia.com>

Add selftest to verify port-level resource functionality using netdevsim.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../drivers/net/netdevsim/devlink.sh          | 32 ++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index 1b529ccaf050..674f0e981ab0 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -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 dev_info_test \
+	   netns_reload_test resource_test port_resource_test dev_info_test \
 	   empty_reporter_test dummy_reporter_test rate_test"
 NUM_NETIFS=0
 source $lib_dir/lib.sh
@@ -856,6 +856,36 @@ rate_test()
 	log_test "rate test"
 }
 
+port_resource_test()
+{
+	RET=0
+
+	local first_port="${DL_HANDLE}/0"
+	local name
+	local size
+
+	devlink port resource show "$first_port" > /dev/null 2>&1
+	check_err $? "Failed to show port resource for $first_port"
+
+	name=$(cmd_jq "devlink port resource show $first_port -j" \
+		      ".[][][].name")
+	[ "$name" == "max_sfs" ]
+	check_err $? "Unexpected resource name $name (expected max_sfs)"
+
+	size=$(cmd_jq "devlink port resource show $first_port -j" \
+		      ".[][][].size")
+	[ "$size" == "20" ]
+	check_err $? "Unexpected resource size $size (expected 20)"
+
+	devlink port resource show "$DL_HANDLE" > /dev/null 2>&1
+	check_err $? "Failed to show port resources for $DL_HANDLE"
+
+	devlink port resource show > /dev/null 2>&1
+	check_err $? "Failed to dump all port resources"
+
+	log_test "port resource test"
+}
+
 setup_prepare()
 {
 	modprobe netdevsim
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 5/5] devlink: Document port-level resources
  2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
                   ` (3 preceding siblings ...)
  2026-02-03  7:10 ` [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test Tariq Toukan
@ 2026-02-03  7:10 ` Tariq Toukan
  2026-02-04  9:56   ` Jiri Pirko
  4 siblings, 1 reply; 14+ messages in thread
From: Tariq Toukan @ 2026-02-03  7:10 UTC (permalink / raw)
  To: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Tariq Toukan, Mark Bloch, Shuah Khan, netdev,
	linux-kernel, linux-doc, linux-rdma, linux-kselftest,
	Gal Pressman, Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

From: Or Har-Toov <ohartoov@nvidia.com>

Add documentation for the port-level resource feature to
devlink-resource.rst. Port-level resources allow viewing resources
associated with specific devlink ports.

Currently, port-level resources only support the show command for
viewing resource information.

Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
 .../networking/devlink/devlink-resource.rst   | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/Documentation/networking/devlink/devlink-resource.rst b/Documentation/networking/devlink/devlink-resource.rst
index 3d5ae51e65a2..4cdfc1dce180 100644
--- a/Documentation/networking/devlink/devlink-resource.rst
+++ b/Documentation/networking/devlink/devlink-resource.rst
@@ -74,3 +74,39 @@ 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
+====================
+
+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.
+
+Currently, port-level resources only support the ``show`` command for viewing
+resource information.
+
+Port-level resources can be viewed for a specific port:
+
+.. code:: shell
+
+    $ devlink port resource show pci/0000:03:00.0/196608
+      pci/0000:03:00.0/196608:
+        name max_sfs size 20 unit entry
+
+Or for ports of a specific device:
+
+.. code:: shell
+
+    $ devlink port resource show pci/0000:03:00.0
+      pci/0000:03:00.0/196608:
+        name max_sfs size 20 unit entry
+
+Or for all ports across all devices:
+
+.. code:: shell
+
+    $ devlink port resource show
+      pci/0000:03:00.0/196608:
+        name max_sfs size 20 unit entry
+      pci/0000:03:00.1/262144:
+        name max_SFs size 20 unit entry
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test
  2026-02-03  7:10 ` [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test Tariq Toukan
@ 2026-02-03 10:16   ` Paolo Abeni
  2026-02-04  2:26     ` Jakub Kicinski
  0 siblings, 1 reply; 14+ messages in thread
From: Paolo Abeni @ 2026-02-03 10:16 UTC (permalink / raw)
  To: Tariq Toukan, Eric Dumazet, Jakub Kicinski, Andrew Lunn,
	David S. Miller
  Cc: Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

On 2/3/26 8:10 AM, Tariq Toukan wrote:
> From: Or Har-Toov <ohartoov@nvidia.com>
> 
> Add selftest to verify port-level resource functionality using netdevsim.
> 
> Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
> Reviewed-by: Shay Drori <shayd@nvidia.com>
> Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
> ---
>  .../drivers/net/netdevsim/devlink.sh          | 32 ++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
> index 1b529ccaf050..674f0e981ab0 100755
> --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
> +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
> @@ -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 dev_info_test \
> +	   netns_reload_test resource_test port_resource_test dev_info_test \
>  	   empty_reporter_test dummy_reporter_test rate_test"
>  NUM_NETIFS=0
>  source $lib_dir/lib.sh
> @@ -856,6 +856,36 @@ rate_test()
>  	log_test "rate test"
>  }
>  
> +port_resource_test()
> +{
> +	RET=0
> +
> +	local first_port="${DL_HANDLE}/0"
> +	local name
> +	local size
> +
> +	devlink port resource show "$first_port" > /dev/null 2>&1
> +	check_err $? "Failed to show port resource for $first_port"
> +
> +	name=$(cmd_jq "devlink port resource show $first_port -j" \
> +		      ".[][][].name")
> +	[ "$name" == "max_sfs" ]
> +	check_err $? "Unexpected resource name $name (expected max_sfs)"
> +
> +	size=$(cmd_jq "devlink port resource show $first_port -j" \
> +		      ".[][][].size")
> +	[ "$size" == "20" ]
> +	check_err $? "Unexpected resource size $size (expected 20)"
> +
> +	devlink port resource show "$DL_HANDLE" > /dev/null 2>&1
> +	check_err $? "Failed to show port resources for $DL_HANDLE"
> +
> +	devlink port resource show > /dev/null 2>&1
> +	check_err $? "Failed to dump all port resources"
> +
> +	log_test "port resource test"
> +}
> +
>  setup_prepare()
>  {
>  	modprobe netdevsim

This test is failing in NIPA (adding some more context beyond the
failing test output just in case it may help):

# Error: netdevsim: Exceeded number of supported fib entries.
# Error: netdevsim: Exceeded number of supported fib entries.
# kernel answers: Operation not permitted
# TEST: resource test                                                 [ OK ]
# Command "resource" not found
# Command "resource" not found
# TEST: port resource test                                            [FAIL]
# Failed to show port resource for netdevsim/netdevsim10/0
# TEST: dev_info test                                                 [ OK ]
# TEST: empty reporter test                                           [ OK ]
# kernel answers: Success
# kernel answers: Success
# ./devlink.sh: line 614: echo: write error: Invalid argument
# Error: netdevsim: User setup the recover to fail for testing purposes.

/P


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test
  2026-02-03 10:16   ` Paolo Abeni
@ 2026-02-04  2:26     ` Jakub Kicinski
  2026-02-04  7:08       ` Tariq Toukan
  0 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2026-02-04  2:26 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Paolo Abeni, Eric Dumazet, Andrew Lunn, David S. Miller,
	Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

On Tue, 3 Feb 2026 11:16:45 +0100 Paolo Abeni wrote:
> # Error: netdevsim: Exceeded number of supported fib entries.
> # Error: netdevsim: Exceeded number of supported fib entries.
> # kernel answers: Operation not permitted
> # TEST: resource test                                                 [ OK ]
> # Command "resource" not found
> # Command "resource" not found
> # TEST: port resource test                                            [FAIL]
> # Failed to show port resource for netdevsim/netdevsim10/0
> # TEST: dev_info test                                                 [ OK ]
> # TEST: empty reporter test                                           [ OK ]
> # kernel answers: Success
> # kernel answers: Success
> # ./devlink.sh: line 614: echo: write error: Invalid argument
> # Error: netdevsim: User setup the recover to fail for testing purposes.

I suppose this is because iproute2 needs patching. Tariq, could you
post the user space bits or share a link where we can pull them from?
I'll revive this in PW once we have CLI updated..

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test
  2026-02-04  2:26     ` Jakub Kicinski
@ 2026-02-04  7:08       ` Tariq Toukan
  0 siblings, 0 replies; 14+ messages in thread
From: Tariq Toukan @ 2026-02-04  7:08 UTC (permalink / raw)
  To: Jakub Kicinski, Tariq Toukan
  Cc: Paolo Abeni, Eric Dumazet, Andrew Lunn, David S. Miller,
	Donald Hunter, Jiri Pirko, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov



On 04/02/2026 4:26, Jakub Kicinski wrote:
> On Tue, 3 Feb 2026 11:16:45 +0100 Paolo Abeni wrote:
>> # Error: netdevsim: Exceeded number of supported fib entries.
>> # Error: netdevsim: Exceeded number of supported fib entries.
>> # kernel answers: Operation not permitted
>> # TEST: resource test                                                 [ OK ]
>> # Command "resource" not found
>> # Command "resource" not found
>> # TEST: port resource test                                            [FAIL]
>> # Failed to show port resource for netdevsim/netdevsim10/0
>> # TEST: dev_info test                                                 [ OK ]
>> # TEST: empty reporter test                                           [ OK ]
>> # kernel answers: Success
>> # kernel answers: Success
>> # ./devlink.sh: line 614: echo: write error: Invalid argument
>> # Error: netdevsim: User setup the recover to fail for testing purposes.
> 
> I suppose this is because iproute2 needs patching. Tariq, could you
> post the user space bits or share a link where we can pull them from?
> I'll revive this in PW once we have CLI updated..
> 

Right. I'll include a pointer in the next submission.
We're fixing the code to fail gracefully (i.e. skip) if userspace 
doesn't have the needed support.



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 1/5] devlink: Add port-level resource infrastructure
  2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
@ 2026-02-04  9:51   ` Jiri Pirko
  2026-02-05 15:26     ` Or Har-Toov
  2026-02-04  9:58   ` Jiri Pirko
  1 sibling, 1 reply; 14+ messages in thread
From: Jiri Pirko @ 2026-02-04  9:51 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Donald Hunter, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

Tue, Feb 03, 2026 at 08:10:29AM +0100, tariqt@nvidia.com wrote:
>From: Or Har-Toov <ohartoov@nvidia.com>
>
>The current devlink resource infrastructure only supports 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 and querying resources at the port level,
>allowing drivers to expose per-port resource limits and usage.
>
>Example output:
>
>  $ devlink port resource show
>  pci/0000:03:00.0/196608:
>    name max_SFs size 20 unit entry
>  pci/0000:03:00.1/262144:
>    name max_SFs size 20 unit entry
>
>  $ devlink port resource show pci/0000:03:00.0/196608
>  pci/0000:03:00.0/196608:
>    name max_SFs size 20 unit entry
>
>Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
>Reviewed-by: Shay Drori <shayd@nvidia.com>
>Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
>Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
>---
> Documentation/netlink/specs/devlink.yaml |  23 ++
> include/net/devlink.h                    |   8 +
> include/uapi/linux/devlink.h             |   2 +
> net/devlink/netlink.c                    |   2 +-
> net/devlink/netlink_gen.c                |  32 ++-
> net/devlink/netlink_gen.h                |   6 +-
> net/devlink/port.c                       |   3 +
> net/devlink/resource.c                   | 282 ++++++++++++++++++-----
> 8 files changed, 301 insertions(+), 57 deletions(-)

Way too big for a single patch. Could you split it in logical chunks
please?


>
>diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
>index 837112da6738..0290db1b8393 100644
>--- a/Documentation/netlink/specs/devlink.yaml
>+++ b/Documentation/netlink/specs/devlink.yaml
>@@ -2336,3 +2336,26 @@ operations:
>             - bus-name
>             - dev-name
>             - port-index
>+
>+    -
>+      name: port-resource-get

Why this is not aligned with DEVLINK_CMD_RESOURCE_* ?
$ git grep CMD_RESOURCE_ include/uapi/linux/devlink.h
include/uapi/linux/devlink.h:   DEVLINK_CMD_RESOURCE_SET,
include/uapi/linux/devlink.h:   DEVLINK_CMD_RESOURCE_DUMP,

I'm aware that DEVLINK_CMD_RESOURCE_DUMP only implements "do" now, but I
think both should be named the same, no?


>+      doc: Get port resources.
>+      attribute-set: devlink
>+      dont-validate: [strict]
>+      do:
>+        pre: devlink-nl-pre-doit-port
>+        post: devlink-nl-post-doit
>+        request:
>+          value: 85
>+          attributes: *port-id-attrs
>+        reply: &port-resource-get-reply
>+          value: 85
>+          attributes:
>+            - bus-name
>+            - dev-name
>+            - port-index
>+            - resource-list
>+      dump:
>+        request:
>+          attributes: *dev-id-attrs
>+        reply: *port-resource-get-reply

[...]


>-int devl_resource_register(struct devlink *devlink,
>-			   const char *resource_name,
>-			   u64 resource_size,
>-			   u64 resource_id,
>-			   u64 parent_resource_id,
>-			   const struct devlink_resource_size_params *size_params)
>+static int
>+devl_resource_reg_by_list(struct devlink *devlink,


can't this be "register"?

Also, why "by_list"? Sounds odd. Could you perhaps have it as
__devl_resource_register(). That's the usual pattern for similar
functions here, isn't it?

Also, could you do this "list" abstraction in a separate patch?



>+			  struct list_head *res_list_head,
>+			  const char *resource_name, u64 resource_size,
>+			  u64 resource_id, u64 parent_res_id,
>+			  const struct devlink_resource_size_params *params)
> {
> 	struct devlink_resource *resource;
> 	struct list_head *resource_list;
>@@ -341,9 +344,10 @@ int devl_resource_register(struct devlink *devlink,
> 
> 	lockdep_assert_held(&devlink->lock);
> 
>-	top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
>+	top_hierarchy = parent_res_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
> 
>-	resource = devlink_resource_find(devlink, NULL, resource_id);
>+	resource = devlink_resource_find_by_list(res_list_head, NULL,
>+						 resource_id);
> 	if (resource)
> 		return -EEXIST;
> 
>@@ -352,15 +356,15 @@ int devl_resource_register(struct devlink *devlink,
> 		return -ENOMEM;
> 
> 	if (top_hierarchy) {
>-		resource_list = &devlink->resource_list;
>+		resource_list = res_list_head;
> 	} else {
>-		struct devlink_resource *parent_resource;
>+		struct devlink_resource *parent_res;
> 
>-		parent_resource = devlink_resource_find(devlink, NULL,
>-							parent_resource_id);
>-		if (parent_resource) {
>-			resource_list = &parent_resource->resource_list;
>-			resource->parent = parent_resource;
>+		parent_res = devlink_resource_find_by_list(res_list_head, NULL,
>+							   parent_res_id);
>+		if (parent_res) {
>+			resource_list = &parent_res->resource_list;
>+			resource->parent = parent_res;
> 		} else {
> 			kfree(resource);
> 			return -EINVAL;
>@@ -372,46 +376,78 @@ int devl_resource_register(struct devlink *devlink,
> 	resource->size_new = resource_size;
> 	resource->id = resource_id;
> 	resource->size_valid = true;
>-	memcpy(&resource->size_params, size_params,
>-	       sizeof(resource->size_params));
>+	memcpy(&resource->size_params, params, sizeof(resource->size_params));
> 	INIT_LIST_HEAD(&resource->resource_list);
> 	list_add_tail(&resource->list, resource_list);
> 
> 	return 0;
> }
>+
>+/**
>+ * devl_resource_register - devlink resource register
>+ *
>+ * @devlink: devlink
>+ * @resource_name: resource's name
>+ * @resource_size: resource's size
>+ * @resource_id: resource's id
>+ * @parent_resource_id: resource's parent id
>+ * @params: size parameters
>+ *
>+ * Generic resources should reuse the same names across drivers.
>+ * Please see the generic resources list at:
>+ * Documentation/networking/devlink/devlink-resource.rst
>+ *
>+ * Return: 0 on success, negative error code otherwise.
>+ */
>+int devl_resource_register(struct devlink *devlink, const char *resource_name,
>+			   u64 resource_size, u64 resource_id,
>+			   u64 parent_resource_id,
>+			   const struct devlink_resource_size_params *params)
>+{
>+	return devl_resource_reg_by_list(devlink, &devlink->resource_list,
>+					      resource_name, resource_size,
>+					      resource_id, parent_resource_id,
>+					      params);
>+}

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 3/5] netdevsim: Add devlink port resource registration
  2026-02-03  7:10 ` [PATCH net-next 3/5] netdevsim: Add devlink port resource registration Tariq Toukan
@ 2026-02-04  9:54   ` Jiri Pirko
  0 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2026-02-04  9:54 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Donald Hunter, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

Tue, Feb 03, 2026 at 08:10:31AM +0100, tariqt@nvidia.com wrote:
>From: Or Har-Toov <ohartoov@nvidia.com>
>
>Register port-level resources for netdevsim ports to enable testing
>of the port resource infrastructure.
>
>Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
>Reviewed-by: Shay Drori <shayd@nvidia.com>
>Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
>Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
>---
> drivers/net/netdevsim/dev.c       | 22 +++++++++++++++++++++-
> drivers/net/netdevsim/netdevsim.h |  4 ++++
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
>index dfd571b22107..ebda1b961664 100644
>--- a/drivers/net/netdevsim/dev.c
>+++ b/drivers/net/netdevsim/dev.c
>@@ -1486,9 +1486,24 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ
> 	if (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, "max_sfs", 20,

Two questions:
1) Why you have "max_sfs" here and "max_SFs" in mlx5? Just curious
2) Why you don't have the name made up completely instead, like "test1"
   or something? It does not really affect anything in netdevsim.



>+						  NSIM_PORT_RESOURCE_MAX_SFS,
>+						  parent_id, &params);
>+		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 +1526,9 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ
> 	nsim_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 +1545,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);
> }
>diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
>index f767fc8a7505..11ea1a52924a 100644
>--- a/drivers/net/netdevsim/netdevsim.h
>+++ b/drivers/net/netdevsim/netdevsim.h
>@@ -224,6 +224,10 @@ enum nsim_resource_id {
> 	NSIM_RESOURCE_NEXTHOPS,
> };
> 
>+enum nsim_port_resource_id {
>+	NSIM_PORT_RESOURCE_MAX_SFS = 1,
>+};
>+
> struct nsim_dev_health {
> 	struct devlink_health_reporter *empty_reporter;
> 	struct devlink_health_reporter *dummy_reporter;
>-- 
>2.40.1
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 5/5] devlink: Document port-level resources
  2026-02-03  7:10 ` [PATCH net-next 5/5] devlink: Document port-level resources Tariq Toukan
@ 2026-02-04  9:56   ` Jiri Pirko
  0 siblings, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2026-02-04  9:56 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Donald Hunter, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

Tue, Feb 03, 2026 at 08:10:33AM +0100, tariqt@nvidia.com wrote:
>From: Or Har-Toov <ohartoov@nvidia.com>
>
>Add documentation for the port-level resource feature to
>devlink-resource.rst. Port-level resources allow viewing resources
>associated with specific devlink ports.
>
>Currently, port-level resources only support the show command for
>viewing resource information.
>
>Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
>Reviewed-by: Shay Drori <shayd@nvidia.com>
>Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
>Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
>---
> .../networking/devlink/devlink-resource.rst   | 36 +++++++++++++++++++
> 1 file changed, 36 insertions(+)
>
>diff --git a/Documentation/networking/devlink/devlink-resource.rst b/Documentation/networking/devlink/devlink-resource.rst
>index 3d5ae51e65a2..4cdfc1dce180 100644
>--- a/Documentation/networking/devlink/devlink-resource.rst
>+++ b/Documentation/networking/devlink/devlink-resource.rst
>@@ -74,3 +74,39 @@ 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
>+====================
>+
>+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.
>+
>+Currently, port-level resources only support the ``show`` command for viewing
>+resource information.
>+
>+Port-level resources can be viewed for a specific port:
>+
>+.. code:: shell
>+
>+    $ devlink port resource show pci/0000:03:00.0/196608
>+      pci/0000:03:00.0/196608:
>+        name max_sfs size 20 unit entry
>+
>+Or for ports of a specific device:
>+
>+.. code:: shell
>+
>+    $ devlink port resource show pci/0000:03:00.0
>+      pci/0000:03:00.0/196608:
>+        name max_sfs size 20 unit entry
>+
>+Or for all ports across all devices:
>+
>+.. code:: shell
>+
>+    $ devlink port resource show
>+      pci/0000:03:00.0/196608:
>+        name max_sfs size 20 unit entry
>+      pci/0000:03:00.1/262144:
>+        name max_SFs size 20 unit entry

"max_SFs" vs "max_sfs", be consistent. Better to copy-paste actual
command output :)



>-- 
>2.40.1
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 1/5] devlink: Add port-level resource infrastructure
  2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
  2026-02-04  9:51   ` Jiri Pirko
@ 2026-02-04  9:58   ` Jiri Pirko
  1 sibling, 0 replies; 14+ messages in thread
From: Jiri Pirko @ 2026-02-04  9:58 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Donald Hunter, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko, Or Har-Toov

Tue, Feb 03, 2026 at 08:10:29AM +0100, tariqt@nvidia.com wrote:
>From: Or Har-Toov <ohartoov@nvidia.com>

[...]

> 
> 	DEVLINK_CMD_NOTIFY_FILTER_SET,
> 
>+	DEVLINK_CMD_PORT_RESOURCE_GET,	/* can dump */

Hmm, I assume that "set" is somehow on the horizon. Wouldn't it make
sense to add the enum as a placeholder to have the cmds
together?


>+
> 	/* add new commands above here */
> 	__DEVLINK_CMD_MAX,
> 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 1/5] devlink: Add port-level resource infrastructure
  2026-02-04  9:51   ` Jiri Pirko
@ 2026-02-05 15:26     ` Or Har-Toov
  0 siblings, 0 replies; 14+ messages in thread
From: Or Har-Toov @ 2026-02-05 15:26 UTC (permalink / raw)
  To: Jiri Pirko, Tariq Toukan
  Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Lunn,
	David S. Miller, Donald Hunter, Jonathan Corbet, Saeed Mahameed,
	Leon Romanovsky, Mark Bloch, Shuah Khan, netdev, linux-kernel,
	linux-doc, linux-rdma, linux-kselftest, Gal Pressman,
	Moshe Shemesh, Shay Drori, Jiri Pirko


On 04/02/2026 11:51, Jiri Pirko wrote:
> External email: Use caution opening links or attachments
>
>
> Tue, Feb 03, 2026 at 08:10:29AM +0100, tariqt@nvidia.com wrote:
>> From: Or Har-Toov <ohartoov@nvidia.com>
>>
>> The current devlink resource infrastructure only supports 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 and querying resources at the port level,
>> allowing drivers to expose per-port resource limits and usage.
>>
>> Example output:
>>
>>   $ devlink port resource show
>>   pci/0000:03:00.0/196608:
>>     name max_SFs size 20 unit entry
>>   pci/0000:03:00.1/262144:
>>     name max_SFs size 20 unit entry
>>
>>   $ devlink port resource show pci/0000:03:00.0/196608
>>   pci/0000:03:00.0/196608:
>>     name max_SFs size 20 unit entry
>>
>> Signed-off-by: Or Har-Toov <ohartoov@nvidia.com>
>> Reviewed-by: Shay Drori <shayd@nvidia.com>
>> Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
>> Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
>> ---
>> Documentation/netlink/specs/devlink.yaml |  23 ++
>> include/net/devlink.h                    |   8 +
>> include/uapi/linux/devlink.h             |   2 +
>> net/devlink/netlink.c                    |   2 +-
>> net/devlink/netlink_gen.c                |  32 ++-
>> net/devlink/netlink_gen.h                |   6 +-
>> net/devlink/port.c                       |   3 +
>> net/devlink/resource.c                   | 282 ++++++++++++++++++-----
>> 8 files changed, 301 insertions(+), 57 deletions(-)
> Way too big for a single patch. Could you split it in logical chunks
> please?
>
>
>> diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
>> index 837112da6738..0290db1b8393 100644
>> --- a/Documentation/netlink/specs/devlink.yaml
>> +++ b/Documentation/netlink/specs/devlink.yaml
>> @@ -2336,3 +2336,26 @@ operations:
>>              - bus-name
>>              - dev-name
>>              - port-index
>> +
>> +    -
>> +      name: port-resource-get
> Why this is not aligned with DEVLINK_CMD_RESOURCE_* ?
> $ git grep CMD_RESOURCE_ include/uapi/linux/devlink.h
> include/uapi/linux/devlink.h:   DEVLINK_CMD_RESOURCE_SET,
> include/uapi/linux/devlink.h:   DEVLINK_CMD_RESOURCE_DUMP,
>
> I'm aware that DEVLINK_CMD_RESOURCE_DUMP only implements "do" now, but I
> think both should be named the same, no?
>
Thanks for the feedback, fixed everything in V2 except for this comment.
Port level operations use get and not dump so I think it make sense to 
align with port and not device level resource
>> +      doc: Get port resources.
>> +      attribute-set: devlink
>> +      dont-validate: [strict]
>> +      do:
>> +        pre: devlink-nl-pre-doit-port
>> +        post: devlink-nl-post-doit
>> +        request:
>> +          value: 85
>> +          attributes: *port-id-attrs
>> +        reply: &port-resource-get-reply
>> +          value: 85
>> +          attributes:
>> +            - bus-name
>> +            - dev-name
>> +            - port-index
>> +            - resource-list
>> +      dump:
>> +        request:
>> +          attributes: *dev-id-attrs
>> +        reply: *port-resource-get-reply
> [...]
>
>
>> -int devl_resource_register(struct devlink *devlink,
>> -                         const char *resource_name,
>> -                         u64 resource_size,
>> -                         u64 resource_id,
>> -                         u64 parent_resource_id,
>> -                         const struct devlink_resource_size_params *size_params)
>> +static int
>> +devl_resource_reg_by_list(struct devlink *devlink,
>
> can't this be "register"?
>
> Also, why "by_list"? Sounds odd. Could you perhaps have it as
> __devl_resource_register(). That's the usual pattern for similar
> functions here, isn't it?
>
> Also, could you do this "list" abstraction in a separate patch?
>
>
>
>> +                        struct list_head *res_list_head,
>> +                        const char *resource_name, u64 resource_size,
>> +                        u64 resource_id, u64 parent_res_id,
>> +                        const struct devlink_resource_size_params *params)
>> {
>>        struct devlink_resource *resource;
>>        struct list_head *resource_list;
>> @@ -341,9 +344,10 @@ int devl_resource_register(struct devlink *devlink,
>>
>>        lockdep_assert_held(&devlink->lock);
>>
>> -      top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
>> +      top_hierarchy = parent_res_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
>>
>> -      resource = devlink_resource_find(devlink, NULL, resource_id);
>> +      resource = devlink_resource_find_by_list(res_list_head, NULL,
>> +                                               resource_id);
>>        if (resource)
>>                return -EEXIST;
>>
>> @@ -352,15 +356,15 @@ int devl_resource_register(struct devlink *devlink,
>>                return -ENOMEM;
>>
>>        if (top_hierarchy) {
>> -              resource_list = &devlink->resource_list;
>> +              resource_list = res_list_head;
>>        } else {
>> -              struct devlink_resource *parent_resource;
>> +              struct devlink_resource *parent_res;
>>
>> -              parent_resource = devlink_resource_find(devlink, NULL,
>> -                                                      parent_resource_id);
>> -              if (parent_resource) {
>> -                      resource_list = &parent_resource->resource_list;
>> -                      resource->parent = parent_resource;
>> +              parent_res = devlink_resource_find_by_list(res_list_head, NULL,
>> +                                                         parent_res_id);
>> +              if (parent_res) {
>> +                      resource_list = &parent_res->resource_list;
>> +                      resource->parent = parent_res;
>>                } else {
>>                        kfree(resource);
>>                        return -EINVAL;
>> @@ -372,46 +376,78 @@ int devl_resource_register(struct devlink *devlink,
>>        resource->size_new = resource_size;
>>        resource->id = resource_id;
>>        resource->size_valid = true;
>> -      memcpy(&resource->size_params, size_params,
>> -             sizeof(resource->size_params));
>> +      memcpy(&resource->size_params, params, sizeof(resource->size_params));
>>        INIT_LIST_HEAD(&resource->resource_list);
>>        list_add_tail(&resource->list, resource_list);
>>
>>        return 0;
>> }
>> +
>> +/**
>> + * devl_resource_register - devlink resource register
>> + *
>> + * @devlink: devlink
>> + * @resource_name: resource's name
>> + * @resource_size: resource's size
>> + * @resource_id: resource's id
>> + * @parent_resource_id: resource's parent id
>> + * @params: size parameters
>> + *
>> + * Generic resources should reuse the same names across drivers.
>> + * Please see the generic resources list at:
>> + * Documentation/networking/devlink/devlink-resource.rst
>> + *
>> + * Return: 0 on success, negative error code otherwise.
>> + */
>> +int devl_resource_register(struct devlink *devlink, const char *resource_name,
>> +                         u64 resource_size, u64 resource_id,
>> +                         u64 parent_resource_id,
>> +                         const struct devlink_resource_size_params *params)
>> +{
>> +      return devl_resource_reg_by_list(devlink, &devlink->resource_list,
>> +                                            resource_name, resource_size,
>> +                                            resource_id, parent_resource_id,
>> +                                            params);
>> +}
> [...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-02-05 15:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-03  7:10 [PATCH net-next 0/5] devlink: add per-port resource support Tariq Toukan
2026-02-03  7:10 ` [PATCH net-next 1/5] devlink: Add port-level resource infrastructure Tariq Toukan
2026-02-04  9:51   ` Jiri Pirko
2026-02-05 15:26     ` Or Har-Toov
2026-02-04  9:58   ` Jiri Pirko
2026-02-03  7:10 ` [PATCH net-next 2/5] net/mlx5: Register SF resource on PF port representor Tariq Toukan
2026-02-03  7:10 ` [PATCH net-next 3/5] netdevsim: Add devlink port resource registration Tariq Toukan
2026-02-04  9:54   ` Jiri Pirko
2026-02-03  7:10 ` [PATCH net-next 4/5] selftest: netdevsim: Add devlink port resource test Tariq Toukan
2026-02-03 10:16   ` Paolo Abeni
2026-02-04  2:26     ` Jakub Kicinski
2026-02-04  7:08       ` Tariq Toukan
2026-02-03  7:10 ` [PATCH net-next 5/5] devlink: Document port-level resources Tariq Toukan
2026-02-04  9:56   ` Jiri Pirko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox