Skip to content

Commit 58dd34d

Browse files
committed
Merge branch 'devlink-add-per-port-resource-support'
Tariq Toukan says: ==================== devlink: add per-port resource support This series by Or adds devlink per-port resource support: 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 ==================== Link: https://patch.msgid.link/20260407194107.148063-1-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 5ae4ba9 + 78c327c commit 58dd34d

15 files changed

Lines changed: 568 additions & 57 deletions

File tree

Documentation/netlink/specs/devlink.yaml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ definitions:
157157
entries:
158158
-
159159
name: entry
160+
-
161+
type: enum
162+
name: resource-scope
163+
entries:
164+
-
165+
name: dev
166+
-
167+
name: port
160168
-
161169
type: enum
162170
name: reload-action
@@ -873,6 +881,16 @@ attribute-sets:
873881
doc: Unique devlink instance index.
874882
checks:
875883
max: u32-max
884+
-
885+
name: resource-scope-mask
886+
type: u32
887+
enum: resource-scope
888+
enum-as-flags: true
889+
doc: |
890+
Bitmask selecting which resource classes to include in a
891+
resource-dump response. Bit 0 (dev) selects device-level
892+
resources; bit 1 (port) selects port-level resources.
893+
When absent all classes are returned.
876894
-
877895
name: dl-dev-stats
878896
subset-of: devlink
@@ -1757,20 +1775,30 @@ operations:
17571775
attribute-set: devlink
17581776
dont-validate: [strict]
17591777
do:
1760-
pre: devlink-nl-pre-doit
1778+
pre: devlink-nl-pre-doit-port-optional
17611779
post: devlink-nl-post-doit
17621780
request:
17631781
attributes:
17641782
- bus-name
17651783
- dev-name
17661784
- index
1767-
reply:
1785+
- port-index
1786+
reply: &resource-dump-reply
17681787
value: 36
17691788
attributes:
17701789
- bus-name
17711790
- dev-name
17721791
- index
1792+
- port-index
17731793
- resource-list
1794+
dump:
1795+
request:
1796+
attributes:
1797+
- bus-name
1798+
- dev-name
1799+
- index
1800+
- resource-scope-mask
1801+
reply: *resource-dump-reply
17741802

17751803
-
17761804
name: reload

Documentation/networking/devlink/devlink-resource.rst

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,73 @@ attribute, which represents the pending change in size. For example:
7474
7575
Note that changes in resource size may require a device reload to properly
7676
take effect.
77+
78+
Port-level Resources and Full Dump
79+
==================================
80+
81+
In addition to device-level resources, ``devlink`` also supports port-level
82+
resources. These resources are associated with a specific devlink port rather
83+
than the device as a whole.
84+
85+
To list resources for all devlink devices and ports:
86+
87+
.. code:: shell
88+
89+
$ devlink resource show
90+
pci/0000:03:00.0:
91+
name max_local_SFs size 128 unit entry dpipe_tables none
92+
name max_external_SFs size 128 unit entry dpipe_tables none
93+
pci/0000:03:00.0/196608:
94+
name max_SFs size 128 unit entry dpipe_tables none
95+
pci/0000:03:00.0/196609:
96+
name max_SFs size 128 unit entry dpipe_tables none
97+
pci/0000:03:00.1:
98+
name max_local_SFs size 128 unit entry dpipe_tables none
99+
name max_external_SFs size 128 unit entry dpipe_tables none
100+
pci/0000:03:00.1/196708:
101+
name max_SFs size 128 unit entry dpipe_tables none
102+
pci/0000:03:00.1/196709:
103+
name max_SFs size 128 unit entry dpipe_tables none
104+
105+
To show resources for a specific port:
106+
107+
.. code:: shell
108+
109+
$ devlink resource show pci/0000:03:00.0/196608
110+
pci/0000:03:00.0/196608:
111+
name max_SFs size 128 unit entry dpipe_tables none
112+
113+
Resource Scope Filtering
114+
========================
115+
116+
When dumping resources for all devices, ``devlink resource show`` accepts
117+
an optional ``scope`` parameter to restrict the response to device-level
118+
resources, port-level resources, or both (the default).
119+
120+
To dump only device-level resources across all devices:
121+
122+
.. code:: shell
123+
124+
$ devlink resource show scope dev
125+
pci/0000:03:00.0:
126+
name max_local_SFs size 128 unit entry dpipe_tables none
127+
name max_external_SFs size 128 unit entry dpipe_tables none
128+
pci/0000:03:00.1:
129+
name max_local_SFs size 128 unit entry dpipe_tables none
130+
name max_external_SFs size 128 unit entry dpipe_tables none
131+
132+
To dump only port-level resources across all devices:
133+
134+
.. code:: shell
135+
136+
$ devlink resource show scope port
137+
pci/0000:03:00.0/196608:
138+
name max_SFs size 128 unit entry dpipe_tables none
139+
pci/0000:03:00.0/196609:
140+
name max_SFs size 128 unit entry dpipe_tables none
141+
pci/0000:03:00.1/196708:
142+
name max_SFs size 128 unit entry dpipe_tables none
143+
pci/0000:03:00.1/196709:
144+
name max_SFs size 128 unit entry dpipe_tables none
145+
146+
Note that port-level resources are read-only.

drivers/net/ethernet/mellanox/mlx5/core/devlink.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ enum mlx5_devlink_resource_id {
1414
MLX5_ID_RES_MAX = __MLX5_ID_RES_MAX - 1,
1515
};
1616

17+
enum mlx5_devlink_port_resource_id {
18+
MLX5_DL_PORT_RES_MAX_SFS = 1,
19+
};
20+
1721
enum mlx5_devlink_param_id {
1822
MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
1923
MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,

drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <linux/mlx5/driver.h>
55
#include "eswitch.h"
6+
#include "devlink.h"
67

78
static void
89
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 = {
158159
.port_fn_max_io_eqs_set = mlx5_devlink_port_fn_max_io_eqs_set,
159160
};
160161

162+
static int mlx5_esw_devlink_port_res_register(struct mlx5_eswitch *esw,
163+
struct devlink_port *dl_port)
164+
{
165+
struct devlink_resource_size_params size_params;
166+
struct mlx5_core_dev *dev = esw->dev;
167+
u16 max_sfs, sf_base_id;
168+
int err;
169+
170+
err = mlx5_esw_sf_max_hpf_functions(dev, &max_sfs, &sf_base_id);
171+
if (err)
172+
return err;
173+
174+
devlink_resource_size_params_init(&size_params, max_sfs, max_sfs, 1,
175+
DEVLINK_RESOURCE_UNIT_ENTRY);
176+
177+
return devl_port_resource_register(dl_port, "max_SFs", max_sfs,
178+
MLX5_DL_PORT_RES_MAX_SFS,
179+
DEVLINK_RESOURCE_ID_PARENT_TOP,
180+
&size_params);
181+
}
182+
183+
static void mlx5_esw_devlink_port_res_unregister(struct devlink_port *dl_port)
184+
{
185+
devl_port_resources_unregister(dl_port);
186+
}
187+
161188
int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
162189
{
163190
struct mlx5_core_dev *dev = esw->dev;
@@ -189,6 +216,15 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlx
189216
if (err)
190217
goto rate_err;
191218

219+
if (vport_num == MLX5_VPORT_PF) {
220+
err = mlx5_esw_devlink_port_res_register(esw,
221+
&dl_port->dl_port);
222+
if (err)
223+
mlx5_core_dbg(dev,
224+
"Failed to register port resources: %d\n",
225+
err);
226+
}
227+
192228
return 0;
193229

194230
rate_err:
@@ -203,6 +239,7 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_vport *vport)
203239
if (!vport->dl_port)
204240
return;
205241
dl_port = vport->dl_port;
242+
mlx5_esw_devlink_port_res_unregister(&dl_port->dl_port);
206243

207244
mlx5_esw_qos_vport_update_parent(vport, NULL, NULL);
208245
devl_rate_leaf_destroy(&dl_port->dl_port);

drivers/net/netdevsim/dev.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1486,9 +1486,25 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ
14861486
if (err)
14871487
goto err_port_free;
14881488

1489+
if (nsim_dev_port_is_pf(nsim_dev_port)) {
1490+
u64 parent_id = DEVLINK_RESOURCE_ID_PARENT_TOP;
1491+
struct devlink_resource_size_params params = {
1492+
.size_max = 100,
1493+
.size_granularity = 1,
1494+
.unit = DEVLINK_RESOURCE_UNIT_ENTRY
1495+
};
1496+
1497+
err = devl_port_resource_register(devlink_port,
1498+
"test_resource", 20,
1499+
NSIM_PORT_RESOURCE_TEST,
1500+
parent_id, &params);
1501+
if (err)
1502+
goto err_dl_port_unregister;
1503+
}
1504+
14891505
err = nsim_dev_port_debugfs_init(nsim_dev, nsim_dev_port);
14901506
if (err)
1491-
goto err_dl_port_unregister;
1507+
goto err_port_resource_unregister;
14921508

14931509
nsim_dev_port->ns = nsim_create(nsim_dev, nsim_dev_port, perm_addr);
14941510
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_typ
15111527
nsim_destroy(nsim_dev_port->ns);
15121528
err_port_debugfs_exit:
15131529
nsim_dev_port_debugfs_exit(nsim_dev_port);
1530+
err_port_resource_unregister:
1531+
if (nsim_dev_port_is_pf(nsim_dev_port))
1532+
devl_port_resources_unregister(devlink_port);
15141533
err_dl_port_unregister:
15151534
devl_port_unregister(devlink_port);
15161535
err_port_free:
@@ -1527,6 +1546,8 @@ static void __nsim_dev_port_del(struct nsim_dev_port *nsim_dev_port)
15271546
devl_rate_leaf_destroy(&nsim_dev_port->devlink_port);
15281547
nsim_destroy(nsim_dev_port->ns);
15291548
nsim_dev_port_debugfs_exit(nsim_dev_port);
1549+
if (nsim_dev_port_is_pf(nsim_dev_port))
1550+
devl_port_resources_unregister(devlink_port);
15301551
devl_port_unregister(devlink_port);
15311552
kfree(nsim_dev_port);
15321553
}

drivers/net/netdevsim/netdevsim.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ enum nsim_resource_id {
224224
NSIM_RESOURCE_NEXTHOPS,
225225
};
226226

227+
enum nsim_port_resource_id {
228+
NSIM_PORT_RESOURCE_TEST = 1,
229+
};
230+
227231
struct nsim_dev_health {
228232
struct devlink_health_reporter *empty_reporter;
229233
struct devlink_health_reporter *dummy_reporter;

include/net/devlink.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ struct devlink_rate {
129129
struct devlink_port {
130130
struct list_head list;
131131
struct list_head region_list;
132+
struct list_head resource_list;
132133
struct devlink *devlink;
133134
const struct devlink_port_ops *ops;
134135
unsigned int index;
@@ -1885,12 +1886,19 @@ int devl_resource_register(struct devlink *devlink,
18851886
u64 resource_size,
18861887
u64 resource_id,
18871888
u64 parent_resource_id,
1888-
const struct devlink_resource_size_params *size_params);
1889+
const struct devlink_resource_size_params *params);
18891890
void devl_resources_unregister(struct devlink *devlink);
18901891
void devlink_resources_unregister(struct devlink *devlink);
18911892
int devl_resource_size_get(struct devlink *devlink,
18921893
u64 resource_id,
18931894
u64 *p_resource_size);
1895+
int
1896+
devl_port_resource_register(struct devlink_port *devlink_port,
1897+
const char *resource_name,
1898+
u64 resource_size, u64 resource_id,
1899+
u64 parent_resource_id,
1900+
const struct devlink_resource_size_params *params);
1901+
void devl_port_resources_unregister(struct devlink_port *devlink_port);
18941902
int devl_dpipe_table_resource_set(struct devlink *devlink,
18951903
const char *table_name, u64 resource_id,
18961904
u64 resource_units);

include/uapi/linux/devlink.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ enum devlink_attr {
645645
DEVLINK_ATTR_PARAM_RESET_DEFAULT, /* flag */
646646

647647
DEVLINK_ATTR_INDEX, /* uint */
648+
DEVLINK_ATTR_RESOURCE_SCOPE_MASK, /* u32 */
648649

649650
/* Add new attributes above here, update the spec in
650651
* Documentation/netlink/specs/devlink.yaml and re-generate
@@ -704,6 +705,16 @@ enum devlink_resource_unit {
704705
DEVLINK_RESOURCE_UNIT_ENTRY,
705706
};
706707

708+
enum devlink_resource_scope {
709+
DEVLINK_RESOURCE_SCOPE_DEV_BIT,
710+
DEVLINK_RESOURCE_SCOPE_PORT_BIT,
711+
};
712+
713+
#define DEVLINK_RESOURCE_SCOPE_DEV \
714+
_BITUL(DEVLINK_RESOURCE_SCOPE_DEV_BIT)
715+
#define DEVLINK_RESOURCE_SCOPE_PORT \
716+
_BITUL(DEVLINK_RESOURCE_SCOPE_PORT_BIT)
717+
707718
enum devlink_port_fn_attr_cap {
708719
DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT,
709720
DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT,

net/devlink/devl_internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ struct devlink_nl_dump_state {
164164
struct {
165165
u64 dump_ts;
166166
};
167+
/* DEVLINK_CMD_RESOURCE_DUMP */
168+
struct {
169+
u32 index;
170+
bool index_valid;
171+
} port_ctx;
167172
};
168173
};
169174

net/devlink/netlink.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg,
370370

371371
/* restart sub-object walk for the next instance */
372372
state->idx = 0;
373+
state->port_ctx.index = 0;
374+
state->port_ctx.index_valid = false;
373375
}
374376

375377
if (err != -EMSGSIZE)

0 commit comments

Comments
 (0)