From: 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 Signed-off-by: Or Har-Toov <[email protected]> Reviewed-by: Moshe Shemesh <[email protected]> Signed-off-by: Tariq Toukan <[email protected]> --- net/devlink/devl_internal.h | 5 ++++ net/devlink/netlink.c | 2 ++ net/devlink/resource.c | 59 ++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h index 7dfb7cdd2d23..e4e48ee2da5a 100644 --- a/net/devlink/devl_internal.h +++ b/net/devlink/devl_internal.h @@ -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; }; }; diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c index 32ddbe244cb7..ae4afc739678 100644 --- a/net/devlink/netlink.c +++ b/net/devlink/netlink.c @@ -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) diff --git a/net/devlink/resource.c b/net/devlink/resource.c index 02fb36e25c52..7984eda63eb6 100644 --- a/net/devlink/resource.c +++ b/net/devlink/resource.c @@ -328,16 +328,20 @@ int devlink_nl_resource_dump_doit(struct sk_buff *skb, struct genl_info *info) } static int -devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, - struct netlink_callback *cb, int flags) +devlink_resource_dump_fill_one(struct sk_buff *skb, struct devlink *devlink, + struct devlink_port *devlink_port, + struct netlink_callback *cb, int flags, int *idx) { - struct devlink_nl_dump_state *state = devlink_dump_state(cb); + struct list_head *resource_list; struct nlattr *resources_attr; - int start_idx = state->idx; + int start_idx = *idx; void *hdr; int err; - if (list_empty(&devlink->resource_list)) + resource_list = devlink_port ? + &devlink_port->resource_list : &devlink->resource_list; + + if (list_empty(resource_list)) return 0; err = -EMSGSIZE; @@ -348,15 +352,17 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, 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) goto nla_put_failure; - err = devlink_resource_list_fill(skb, devlink, - &devlink->resource_list, &state->idx); + err = devlink_resource_list_fill(skb, devlink, resource_list, idx); if (err) { - if (state->idx == start_idx) + if (*idx == start_idx) goto resource_list_cancel; nla_nest_end(skb, resources_attr); genlmsg_end(skb, hdr); @@ -373,6 +379,43 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, return err; } +static int +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); + struct devlink_port *devlink_port; + unsigned long port_idx; + int err; + + if (!state->port_ctx.index_valid) { + err = devlink_resource_dump_fill_one(skb, devlink, NULL, + cb, flags, &state->idx); + if (err) + return err; + state->idx = 0; + } + + /* Check in case port was removed between dump callbacks. */ + if (state->port_ctx.index_valid && + !xa_load(&devlink->ports, state->port_ctx.index)) + state->idx = 0; + state->port_ctx.index_valid = true; + xa_for_each_start(&devlink->ports, port_idx, devlink_port, + state->port_ctx.index) { + err = devlink_resource_dump_fill_one(skb, devlink, devlink_port, + cb, flags, &state->idx); + if (err) { + state->port_ctx.index = port_idx; + return err; + } + state->idx = 0; + } + state->port_ctx.index_valid = false; + state->port_ctx.index = 0; + return 0; +} + int devlink_nl_resource_dump_dumpit(struct sk_buff *skb, struct netlink_callback *cb) { -- 2.44.0

