Commit f3cc0030 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'devlink-introduce-selective-dumps'

Jiri Pirko says:

====================
devlink: introduce selective dumps

Motivation:

For SFs, one devlink instance per SF is created. There might be
thousands of these on a single host. When a user needs to know port
handle for specific SF, he needs to dump all devlink ports on the host
which does not scale good.

Solution:

Allow user to pass devlink handle (and possibly other attributes)
alongside the dump command and dump only objects which are matching
the selection.

Use split ops to generate policies for dump callbacks acccording to
the attributes used for selection.

The userspace can use ctrl genetlink GET_POLICY command to find out if
the selective dumps are supported by kernel for particular command.

Example:
$ devlink port show
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

$ devlink port show auxiliary/mlx5_core.eth.0
auxiliary/mlx5_core.eth.0/65535: type eth netdev eth2 flavour physical port 0 splittable false

$ devlink port show auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1/131071: type eth netdev eth3 flavour physical port 1 splittable false

Extension:

patches #12 and #13 extends selection attributes by port index
for health reporter dumping.
====================

Link: https://lore.kernel.org/r/20230811155714.1736405-1-jiri@resnulli.us


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 83b5f025 0149bca1
Loading
Loading
Loading
Loading
+456 −1
Original line number Diff line number Diff line
@@ -6,6 +6,16 @@ protocol: genetlink-legacy

doc: Partial family for Devlink.

definitions:
  -
    type: enum
    name: sb-pool-type
    entries:
      -
        name: ingress
      -
        name: egress

attribute-sets:
  -
    name: devlink
@@ -24,6 +34,46 @@ attribute-sets:

      # TODO: fill in the attributes in between

      -
        name: sb-index
        type: u32
        value: 11

      # TODO: fill in the attributes in between

      -
        name: sb-pool-index
        type: u16
        value: 17

      -
        name: sb-pool-type
        type: u8
        enum: sb-pool-type

      # TODO: fill in the attributes in between

      -
        name: sb-tc-index
        type: u16
        value: 22

      # TODO: fill in the attributes in between

      -
        name: param-name
        type: string
        value: 81

      # TODO: fill in the attributes in between

      -
        name: region-name
        type: string
        value: 88

      # TODO: fill in the attributes in between

      -
        name: info-driver-name
        type: string
@@ -55,10 +105,35 @@ attribute-sets:

      # TODO: fill in the attributes in between

      -
        name: health-reporter-name
        type: string
        value: 115

      # TODO: fill in the attributes in between

      -
        name: trap-name
        type: string
        value: 130

      # TODO: fill in the attributes in between

      -
        name: trap-group-name
        type: string
        value: 135

      -
        name: reload-failed
        type: u8
        value: 136

      # TODO: fill in the attributes in between

      -
        name: trap-policer-id
        type: u32
        value: 142

      # TODO: fill in the attributes in between

@@ -103,6 +178,21 @@ attribute-sets:
        type: nest
        multi-attr: true
        nested-attributes: dl-reload-act-stats

      # TODO: fill in the attributes in between

      -
        name: rate-node-name
        type: string
        value: 168

      # TODO: fill in the attributes in between

      -
        name: linecard-index
        type: u32
        value: 171

  -
    name: dl-dev-stats
    subset-of: devlink
@@ -188,6 +278,195 @@ operations:
      dump:
        reply: *get-reply

    -
      name: port-get
      doc: Get devlink port instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit-port
        post: devlink-nl-post-doit
        request:
          value: 5
          attributes: &port-id-attrs
            - bus-name
            - dev-name
            - port-index
        reply:
          value: 7
          attributes: *port-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply:
          value: 3  # due to a bug, port dump returns DEVLINK_CMD_NEW
          attributes: *port-id-attrs

      # TODO: fill in the operations in between

    -
      name: sb-get
      doc: Get shared buffer instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 11
          attributes: &sb-id-attrs
            - bus-name
            - dev-name
            - sb-index
        reply: &sb-get-reply
          value: 11
          attributes: *sb-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *sb-get-reply

      # TODO: fill in the operations in between

    -
      name: sb-pool-get
      doc: Get shared buffer pool instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 15
          attributes: &sb-pool-id-attrs
            - bus-name
            - dev-name
            - sb-index
            - sb-pool-index
        reply: &sb-pool-get-reply
          value: 15
          attributes: *sb-pool-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *sb-pool-get-reply

      # TODO: fill in the operations in between

    -
      name: sb-port-pool-get
      doc: Get shared buffer port-pool combinations and threshold.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit-port
        post: devlink-nl-post-doit
        request:
          value: 19
          attributes: &sb-port-pool-id-attrs
            - bus-name
            - dev-name
            - port-index
            - sb-index
            - sb-pool-index
        reply: &sb-port-pool-get-reply
          value: 19
          attributes: *sb-port-pool-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *sb-port-pool-get-reply

      # TODO: fill in the operations in between

    -
      name: sb-tc-pool-bind-get
      doc: Get shared buffer port-TC to pool bindings and threshold.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit-port
        post: devlink-nl-post-doit
        request:
          value: 23
          attributes: &sb-tc-pool-bind-id-attrs
            - bus-name
            - dev-name
            - port-index
            - sb-index
            - sb-pool-type
            - sb-tc-index
        reply: &sb-tc-pool-bind-get-reply
          value: 23
          attributes: *sb-tc-pool-bind-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *sb-tc-pool-bind-get-reply

      # TODO: fill in the operations in between

    -
      name: param-get
      doc: Get param instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 38
          attributes: &param-id-attrs
            - bus-name
            - dev-name
            - param-name
        reply: &param-get-reply
          value: 38
          attributes: *param-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *param-get-reply

      # TODO: fill in the operations in between

    -
      name: region-get
      doc: Get region instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit-port-optional
        post: devlink-nl-post-doit
        request:
          value: 42
          attributes: &region-id-attrs
            - bus-name
            - dev-name
            - port-index
            - region-name
        reply: &region-get-reply
          value: 42
          attributes: *region-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *region-get-reply

      # TODO: fill in the operations in between

    -
@@ -216,3 +495,179 @@ operations:
            - info-version-stored
      dump:
        reply: *info-get-reply

    -
      name: health-reporter-get
      doc: Get health reporter instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit-port-optional
        post: devlink-nl-post-doit
        request:
          attributes: &health-reporter-id-attrs
            - bus-name
            - dev-name
            - port-index
            - health-reporter-name
        reply: &health-reporter-get-reply
          attributes: *health-reporter-id-attrs
      dump:
        request:
          attributes: *port-id-attrs
        reply: *health-reporter-get-reply

      # TODO: fill in the operations in between

    -
      name: trap-get
      doc: Get trap instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 61
          attributes: &trap-id-attrs
            - bus-name
            - dev-name
            - trap-name
        reply: &trap-get-reply
          value: 61
          attributes: *trap-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *trap-get-reply

      # TODO: fill in the operations in between

    -
      name: trap-group-get
      doc: Get trap group instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 65
          attributes: &trap-group-id-attrs
            - bus-name
            - dev-name
            - trap-group-name
        reply: &trap-group-get-reply
          value: 65
          attributes: *trap-group-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *trap-group-get-reply

      # TODO: fill in the operations in between

    -
      name: trap-policer-get
      doc: Get trap policer instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 69
          attributes: &trap-policer-id-attrs
            - bus-name
            - dev-name
            - trap-policer-id
        reply: &trap-policer-get-reply
          value: 69
          attributes: *trap-policer-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *trap-policer-get-reply

      # TODO: fill in the operations in between

    -
      name: rate-get
      doc: Get rate instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 74
          attributes: &rate-id-attrs
            - bus-name
            - dev-name
            - port-index
            - rate-node-name
        reply: &rate-get-reply
          value: 74
          attributes: *rate-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *rate-get-reply

      # TODO: fill in the operations in between

    -
      name: linecard-get
      doc: Get line card instances.
      attribute-set: devlink
      dont-validate:
        - strict

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 78
          attributes: &linecard-id-attrs
            - bus-name
            - dev-name
            - linecard-index
        reply: &linecard-get-reply
          value: 78
          attributes: *linecard-id-attrs
      dump:
        request:
          attributes: *dev-id-attrs
        reply: *linecard-get-reply

      # TODO: fill in the operations in between

    -
      name: selftests-get
      doc: Get device selftest instances.
      attribute-set: devlink
      dont-validate:
        - strict
        - dump

      do:
        pre: devlink-nl-pre-doit
        post: devlink-nl-post-doit
        request:
          value: 82
          attributes: *dev-id-attrs
        reply: &selftests-get-reply
          value: 82
          attributes: *dev-id-attrs
      dump:
        reply: *selftests-get-reply
+15 −14
Original line number Diff line number Diff line
@@ -218,11 +218,11 @@ int devlink_nl_get_doit(struct sk_buff *skb, struct genl_info *info)

static int
devlink_nl_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
			struct netlink_callback *cb)
			struct netlink_callback *cb, int flags)
{
	return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
			       NETLINK_CB(cb->skb).portid,
			       cb->nlh->nlmsg_seq, NLM_F_MULTI);
			       cb->nlh->nlmsg_seq, flags);
}

int devlink_nl_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb)
@@ -828,13 +828,13 @@ int devlink_nl_info_get_doit(struct sk_buff *skb, struct genl_info *info)

static int
devlink_nl_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
			     struct netlink_callback *cb)
			     struct netlink_callback *cb, int flags)
{
	int err;

	err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
				   NETLINK_CB(cb->skb).portid,
				   cb->nlh->nlmsg_seq, NLM_F_MULTI,
				   cb->nlh->nlmsg_seq, flags,
				   cb->extack);
	if (err == -EOPNOTSUPP)
		err = 0;
@@ -1206,8 +1206,7 @@ devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
	return err;
}

int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
				      struct genl_info *info)
int devlink_nl_selftests_get_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct devlink *devlink = info->user_ptr[0];
	struct sk_buff *msg;
@@ -1230,23 +1229,25 @@ int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
	return genlmsg_reply(msg, info);
}

static int
devlink_nl_cmd_selftests_get_dump_one(struct sk_buff *msg,
static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg,
					     struct devlink *devlink,
				      struct netlink_callback *cb)
					     struct netlink_callback *cb,
					     int flags)
{
	if (!devlink->ops->selftest_check)
		return 0;

	return devlink_nl_selftests_fill(msg, devlink,
					 NETLINK_CB(cb->skb).portid,
					 cb->nlh->nlmsg_seq, NLM_F_MULTI,
					 cb->nlh->nlmsg_seq, flags,
					 cb->extack);
}

const struct devlink_cmd devl_cmd_selftests_get = {
	.dump_one		= devlink_nl_cmd_selftests_get_dump_one,
};
int devlink_nl_selftests_get_dumpit(struct sk_buff *skb,
				    struct netlink_callback *cb)
{
	return devlink_nl_dumpit(skb, cb, devlink_nl_selftests_get_dump_one);
}

static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
				       enum devlink_selftest_status test_status)
+4 −40
Original line number Diff line number Diff line
@@ -92,9 +92,6 @@ static inline bool devl_is_registered(struct devlink *devlink)
/* Netlink */
#define DEVLINK_NL_FLAG_NEED_PORT		BIT(0)
#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT	BIT(1)
#define DEVLINK_NL_FLAG_NEED_RATE		BIT(2)
#define DEVLINK_NL_FLAG_NEED_RATE_NODE		BIT(3)
#define DEVLINK_NL_FLAG_NEED_LINECARD		BIT(4)

enum devlink_multicast_groups {
	DEVLINK_MCGRP_CONFIG,
@@ -118,13 +115,10 @@ struct devlink_nl_dump_state {

typedef int devlink_nl_dump_one_func_t(struct sk_buff *msg,
				       struct devlink *devlink,
				       struct netlink_callback *cb);

struct devlink_cmd {
	devlink_nl_dump_one_func_t *dump_one;
};
				       struct netlink_callback *cb,
				       int flags);

extern const struct genl_small_ops devlink_nl_small_ops[54];
extern const struct genl_small_ops devlink_nl_small_ops[40];

struct devlink *
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs);
@@ -134,7 +128,6 @@ void devlink_notify_register(struct devlink *devlink);

int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
		      devlink_nl_dump_one_func_t *dump_one);
int devlink_nl_instance_iter_dumpit(struct sk_buff *msg, struct netlink_callback *cb);

static inline struct devlink_nl_dump_state *
devlink_dump_state(struct netlink_callback *cb)
@@ -154,22 +147,6 @@ devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
	return 0;
}

/* Commands */
extern const struct devlink_cmd devl_cmd_port_get;
extern const struct devlink_cmd devl_cmd_sb_get;
extern const struct devlink_cmd devl_cmd_sb_pool_get;
extern const struct devlink_cmd devl_cmd_sb_port_pool_get;
extern const struct devlink_cmd devl_cmd_sb_tc_pool_bind_get;
extern const struct devlink_cmd devl_cmd_param_get;
extern const struct devlink_cmd devl_cmd_region_get;
extern const struct devlink_cmd devl_cmd_health_reporter_get;
extern const struct devlink_cmd devl_cmd_trap_get;
extern const struct devlink_cmd devl_cmd_trap_group_get;
extern const struct devlink_cmd devl_cmd_trap_policer_get;
extern const struct devlink_cmd devl_cmd_rate_get;
extern const struct devlink_cmd devl_cmd_linecard_get;
extern const struct devlink_cmd devl_cmd_selftests_get;

/* Notify */
void devlink_notify(struct devlink *devlink, enum devlink_command cmd);

@@ -203,29 +180,16 @@ int devlink_resources_validate(struct devlink *devlink,
			       struct devlink_resource *resource,
			       struct genl_info *info);

/* Line cards */
struct devlink_linecard;

struct devlink_linecard *
devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info);

/* Rates */
int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
			     struct netlink_ext_ack *extack);
struct devlink_rate *
devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info);
struct devlink_rate *
devlink_rate_node_get_from_info(struct devlink *devlink,
				struct genl_info *info);

/* Devlink nl cmds */
int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_flash_update(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_selftests_run(struct sk_buff *skb, struct genl_info *info);
int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
					    struct genl_info *info);
int devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
					    struct genl_info *info);
int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
+28 −12
Original line number Diff line number Diff line
@@ -356,7 +356,7 @@ devlink_health_reporter_get_from_info(struct devlink *devlink,
	return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
}

int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
int devlink_nl_health_reporter_get_doit(struct sk_buff *skb,
					struct genl_info *info)
{
	struct devlink *devlink = info->user_ptr[0];
@@ -384,18 +384,29 @@ int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
	return genlmsg_reply(msg, info);
}

static int
devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
static int devlink_nl_health_reporter_get_dump_one(struct sk_buff *msg,
						   struct devlink *devlink,
					    struct netlink_callback *cb)
						   struct netlink_callback *cb,
						   int flags)
{
	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
	struct devlink_health_reporter *reporter;
	unsigned long port_index_end = ULONG_MAX;
	struct nlattr **attrs = info->attrs;
	unsigned long port_index_start = 0;
	struct devlink_port *port;
	unsigned long port_index;
	int idx = 0;
	int err;

	if (attrs && attrs[DEVLINK_ATTR_PORT_INDEX]) {
		port_index_start = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
		port_index_end = port_index_start;
		flags |= NLM_F_DUMP_FILTERED;
		goto per_port_dump;
	}

	list_for_each_entry(reporter, &devlink->reporter_list, list) {
		if (idx < state->idx) {
			idx++;
@@ -405,14 +416,16 @@ devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
						      DEVLINK_CMD_HEALTH_REPORTER_GET,
						      NETLINK_CB(cb->skb).portid,
						      cb->nlh->nlmsg_seq,
						      NLM_F_MULTI);
						      flags);
		if (err) {
			state->idx = idx;
			return err;
		}
		idx++;
	}
	xa_for_each(&devlink->ports, port_index, port) {
per_port_dump:
	xa_for_each_range(&devlink->ports, port_index, port,
			  port_index_start, port_index_end) {
		list_for_each_entry(reporter, &port->reporter_list, list) {
			if (idx < state->idx) {
				idx++;
@@ -422,7 +435,7 @@ devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
							      DEVLINK_CMD_HEALTH_REPORTER_GET,
							      NETLINK_CB(cb->skb).portid,
							      cb->nlh->nlmsg_seq,
							      NLM_F_MULTI);
							      flags);
			if (err) {
				state->idx = idx;
				return err;
@@ -434,9 +447,12 @@ devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
	return 0;
}

const struct devlink_cmd devl_cmd_health_reporter_get = {
	.dump_one		= devlink_nl_cmd_health_reporter_get_dump_one,
};
int devlink_nl_health_reporter_get_dumpit(struct sk_buff *skb,
					  struct netlink_callback *cb)
{
	return devlink_nl_dumpit(skb, cb,
				 devlink_nl_health_reporter_get_dump_one);
}

int devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
					    struct genl_info *info)
+174 −245

File changed.

Preview size limit exceeded, changes collapsed.

Loading