From: Or Har-Toov 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 none Example - 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 Signed-off-by: Or Har-Toov Reviewed-by: Moshe Shemesh Signed-off-by: Tariq Toukan --- Documentation/netlink/specs/devlink.yaml | 24 +++++++++++++++++- include/uapi/linux/devlink.h | 17 +++++++++++++ net/devlink/netlink_gen.c | 5 ++-- net/devlink/resource.c | 32 ++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml index 34aa81ba689e..b7d0490fc49d 100644 --- a/Documentation/netlink/specs/devlink.yaml +++ b/Documentation/netlink/specs/devlink.yaml @@ -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: bitfield32 + 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 - diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 7de2d8cc862f..e0a0b523ce5c 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -645,6 +645,7 @@ enum devlink_attr { DEVLINK_ATTR_PARAM_RESET_DEFAULT, /* flag */ DEVLINK_ATTR_INDEX, /* uint */ + DEVLINK_ATTR_RESOURCE_SCOPE_MASK, /* bitfield32 */ /* Add new attributes above here, update the spec in * Documentation/netlink/specs/devlink.yaml and re-generate @@ -704,6 +705,22 @@ enum devlink_resource_unit { DEVLINK_RESOURCE_UNIT_ENTRY, }; +enum devlink_resource_scope { + DEVLINK_RESOURCE_SCOPE_DEV_BIT, + DEVLINK_RESOURCE_SCOPE_PORT_BIT, + + __DEVLINK_RESOURCE_SCOPE_MAX_BIT, + DEVLINK_RESOURCE_SCOPE_MAX_BIT = + __DEVLINK_RESOURCE_SCOPE_MAX_BIT - 1 +}; + +#define DEVLINK_RESOURCE_SCOPE_DEV \ + _BITUL(DEVLINK_RESOURCE_SCOPE_DEV_BIT) +#define DEVLINK_RESOURCE_SCOPE_PORT \ + _BITUL(DEVLINK_RESOURCE_SCOPE_PORT_BIT) +#define DEVLINK_RESOURCE_SCOPE_VALID_MASK \ + (_BITUL(__DEVLINK_RESOURCE_SCOPE_MAX_BIT) - 1) + enum devlink_port_fn_attr_cap { DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT, DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT, diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c index 9cc372d9ee41..6d4abd8b828d 100644 --- a/net/devlink/netlink_gen.c +++ b/net/devlink/netlink_gen.c @@ -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_BITFIELD32(3), }; /* 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, }, { diff --git a/net/devlink/resource.c b/net/devlink/resource.c index 0f1d90bc4b09..c22338b2571d 100644 --- a/net/devlink/resource.c +++ b/net/devlink/resource.c @@ -341,6 +341,22 @@ int devlink_nl_resource_dump_doit(struct sk_buff *skb, struct genl_info *info) return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); } +static u32 devlink_resource_scope_get(struct nlattr **attrs, int *flags) +{ + struct nla_bitfield32 scope; + u32 value; + + if (!attrs || !attrs[DEVLINK_ATTR_RESOURCE_SCOPE_MASK]) + return DEVLINK_RESOURCE_SCOPE_VALID_MASK; + + scope = nla_get_bitfield32(attrs[DEVLINK_ATTR_RESOURCE_SCOPE_MASK]); + value = scope.value & scope.selector; + if (value != DEVLINK_RESOURCE_SCOPE_VALID_MASK) + *flags |= NLM_F_DUMP_FILTERED; + + return value; +} + static int devlink_resource_dump_fill_one(struct sk_buff *skb, struct devlink *devlink, struct devlink_port *devlink_port, @@ -400,16 +416,27 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_port *devlink_port; unsigned long port_idx; + u32 scope; int err; - if (!state->port_number) { + scope = devlink_resource_scope_get(genl_info_dump(cb)->attrs, &flags); + if (!scope) { + NL_SET_ERR_MSG_ATTR(genl_info_dump(cb)->extack, + genl_info_dump(cb)->attrs[DEVLINK_ATTR_RESOURCE_SCOPE_MASK], + "empty resource scope selection"); + return -EINVAL; + } + if (!state->port_number && (scope & DEVLINK_RESOURCE_SCOPE_DEV)) { err = devlink_resource_dump_fill_one(skb, devlink, NULL, - cb, flags, &state->idx); + cb, flags, + &state->idx); if (err) return err; state->idx = 0; } + if (!(scope & DEVLINK_RESOURCE_SCOPE_PORT)) + goto out; xa_for_each_start(&devlink->ports, port_idx, devlink_port, state->port_number ? state->port_number - 1 : 0) { err = devlink_resource_dump_fill_one(skb, devlink, devlink_port, @@ -420,6 +447,7 @@ devlink_nl_resource_dump_one(struct sk_buff *skb, struct devlink *devlink, } state->idx = 0; } +out: state->port_number = 0; return 0; } -- 2.44.0