Skip to content

Commit

Permalink
Merge branch 'devlink-introduce-selective-dumps'
Browse files Browse the repository at this point in the history
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: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Aug 14, 2023
2 parents 83b5f02 + 0149bca commit f3cc003
Show file tree
Hide file tree
Showing 10 changed files with 5,327 additions and 506 deletions.
457 changes: 456 additions & 1 deletion Documentation/netlink/specs/devlink.yaml

Large diffs are not rendered by default.

29 changes: 15 additions & 14 deletions net/devlink/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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,
struct devlink *devlink,
struct netlink_callback *cb)
static int devlink_nl_selftests_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
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)
Expand Down
44 changes: 4 additions & 40 deletions net/devlink/devl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 netlink_callback *cb,
int flags);

struct devlink_cmd {
devlink_nl_dump_one_func_t *dump_one;
};

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);
Expand All @@ -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)
Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down
40 changes: 28 additions & 12 deletions net/devlink/health.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ 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,
struct genl_info *info)
int devlink_nl_health_reporter_get_doit(struct sk_buff *skb,
struct genl_info *info)
{
struct devlink *devlink = info->user_ptr[0];
struct devlink_health_reporter *reporter;
Expand All @@ -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,
struct devlink *devlink,
struct netlink_callback *cb)
static int devlink_nl_health_reporter_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);
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++;
Expand All @@ -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++;
Expand All @@ -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;
Expand All @@ -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)
Expand Down
Loading

0 comments on commit f3cc003

Please sign in to comment.