Commit 5ce76d78 authored by Jakub Kicinski's avatar Jakub Kicinski

devlink: convert remaining dumps to the by-instance scheme

Soon we'll have to check if a devlink instance is alive after
locking it. Convert to the by-instance dumping scheme to make
refactoring easier.

Most of the subobject code no longer has to worry about any devlink
locking / lifetime rules (the only ones that still do are the two subject
types which stubbornly use their own locking). Both dump and do callbacks
are given a devlink instance which is already locked and good-to-access
(do from the .pre_doit handler, dump from the new dump indirection).

Note that we'll now check presence of an op (e.g. for sb_pool_get)
under the devlink instance lock, that will soon be necessary anyway,
because we don't hold refs on the driver modules so the memory
in which ops live may be gone for a dead instance, after upcoming
locking changes.
Reviewed-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 07f3af66
...@@ -156,6 +156,21 @@ devlink_dump_state(struct netlink_callback *cb) ...@@ -156,6 +156,21 @@ devlink_dump_state(struct netlink_callback *cb)
return (struct devlink_nl_dump_state *)cb->ctx; return (struct devlink_nl_dump_state *)cb->ctx;
} }
/* gen cmds */
extern const struct devlink_gen_cmd devl_gen_inst;
extern const struct devlink_gen_cmd devl_gen_port;
extern const struct devlink_gen_cmd devl_gen_sb;
extern const struct devlink_gen_cmd devl_gen_sb_pool;
extern const struct devlink_gen_cmd devl_gen_sb_port_pool;
extern const struct devlink_gen_cmd devl_gen_sb_tc_pool_bind;
extern const struct devlink_gen_cmd devl_gen_selftests;
extern const struct devlink_gen_cmd devl_gen_param;
extern const struct devlink_gen_cmd devl_gen_region;
extern const struct devlink_gen_cmd devl_gen_info;
extern const struct devlink_gen_cmd devl_gen_trap;
extern const struct devlink_gen_cmd devl_gen_trap_group;
extern const struct devlink_gen_cmd devl_gen_trap_policer;
/* Ports */ /* Ports */
int devlink_port_netdevice_event(struct notifier_block *nb, int devlink_port_netdevice_event(struct notifier_block *nb,
unsigned long event, void *ptr); unsigned long event, void *ptr);
......
...@@ -1307,28 +1307,19 @@ static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info) ...@@ -1307,28 +1307,19 @@ static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
return genlmsg_reply(msg, info); return genlmsg_reply(msg, info);
} }
static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
devl_lock(devlink);
err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI); cb->nlh->nlmsg_seq, NLM_F_MULTI);
devl_unlock(devlink);
devlink_put(devlink);
if (err)
goto out;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_inst = {
.dump_one = devlink_nl_cmd_get_dump_one,
};
static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
...@@ -1351,19 +1342,16 @@ static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb, ...@@ -1351,19 +1342,16 @@ static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
return genlmsg_reply(msg, info); return genlmsg_reply(msg, info);
} }
static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_port *devlink_port; struct devlink_port *devlink_port;
unsigned long port_index; unsigned long port_index;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink);
xa_for_each(&devlink->ports, port_index, devlink_port) { xa_for_each(&devlink->ports, port_index, devlink_port) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
...@@ -1375,20 +1363,19 @@ static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg, ...@@ -1375,20 +1363,19 @@ static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI, cb->extack); NLM_F_MULTI, cb->extack);
if (err) { if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink); return err;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_port = {
.dump_one = devlink_nl_cmd_port_get_dump_one,
};
static int devlink_port_type_set(struct devlink_port *devlink_port, static int devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type port_type) enum devlink_port_type port_type)
...@@ -2393,18 +2380,15 @@ static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb, ...@@ -2393,18 +2380,15 @@ static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
return genlmsg_reply(msg, info); return genlmsg_reply(msg, info);
} }
static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_sb *devlink_sb; struct devlink_sb *devlink_sb;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink);
list_for_each_entry(devlink_sb, &devlink->sb_list, list) { list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
...@@ -2416,20 +2400,19 @@ static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg, ...@@ -2416,20 +2400,19 @@ static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI); NLM_F_MULTI);
if (err) { if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink); return err;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_sb = {
.dump_one = devlink_nl_cmd_sb_get_dump_one,
};
static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink, static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
struct devlink_sb *devlink_sb, struct devlink_sb *devlink_sb,
u16 pool_index, enum devlink_command cmd, u16 pool_index, enum devlink_command cmd,
...@@ -2535,21 +2518,19 @@ static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, ...@@ -2535,21 +2518,19 @@ static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
return 0; return 0;
} }
static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_sb *devlink_sb; struct devlink_sb *devlink_sb;
int err = 0;
int idx = 0; int idx = 0;
if (!devlink->ops->sb_pool_get) if (!devlink->ops->sb_pool_get)
goto retry; return 0;
devl_lock(devlink);
list_for_each_entry(devlink_sb, &devlink->sb_list, list) { list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
err = __sb_pool_get_dumpit(msg, state->idx, &idx, err = __sb_pool_get_dumpit(msg, state->idx, &idx,
devlink, devlink_sb, devlink, devlink_sb,
...@@ -2558,23 +2539,18 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, ...@@ -2558,23 +2539,18 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
if (err == -EOPNOTSUPP) { if (err == -EOPNOTSUPP) {
err = 0; err = 0;
} else if (err) { } else if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
} }
devl_unlock(devlink);
retry:
devlink_put(devlink);
}
out:
if (err != -EMSGSIZE)
return err;
return msg->len; return err;
} }
const struct devlink_gen_cmd devl_gen_sb_pool = {
.dump_one = devlink_nl_cmd_sb_pool_get_dump_one,
};
static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
u16 pool_index, u32 size, u16 pool_index, u32 size,
enum devlink_sb_threshold_type threshold_type, enum devlink_sb_threshold_type threshold_type,
...@@ -2750,21 +2726,19 @@ static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx, ...@@ -2750,21 +2726,19 @@ static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
return 0; return 0;
} }
static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_sb *devlink_sb; struct devlink_sb *devlink_sb;
int idx = 0; int idx = 0;
int err = 0;
if (!devlink->ops->sb_port_pool_get) if (!devlink->ops->sb_port_pool_get)
goto retry; return 0;
devl_lock(devlink);
list_for_each_entry(devlink_sb, &devlink->sb_list, list) { list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
err = __sb_port_pool_get_dumpit(msg, state->idx, &idx, err = __sb_port_pool_get_dumpit(msg, state->idx, &idx,
devlink, devlink_sb, devlink, devlink_sb,
...@@ -2773,23 +2747,18 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, ...@@ -2773,23 +2747,18 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
if (err == -EOPNOTSUPP) { if (err == -EOPNOTSUPP) {
err = 0; err = 0;
} else if (err) { } else if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
}
} }
devl_unlock(devlink);
retry:
devlink_put(devlink);
} }
out:
if (err != -EMSGSIZE)
return err;
return msg->len; return err;
} }
const struct devlink_gen_cmd devl_gen_sb_port_pool = {
.dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one,
};
static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
unsigned int sb_index, u16 pool_index, unsigned int sb_index, u16 pool_index,
u32 threshold, u32 threshold,
...@@ -2993,21 +2962,18 @@ static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, ...@@ -2993,21 +2962,18 @@ static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
} }
static int static int
devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_sb *devlink_sb; struct devlink_sb *devlink_sb;
int idx = 0; int idx = 0;
int err = 0;
if (!devlink->ops->sb_tc_pool_bind_get) if (!devlink->ops->sb_tc_pool_bind_get)
goto retry; return 0;
devl_lock(devlink);
list_for_each_entry(devlink_sb, &devlink->sb_list, list) { list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx, err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx,
devlink, devlink_sb, devlink, devlink_sb,
...@@ -3016,23 +2982,18 @@ devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, ...@@ -3016,23 +2982,18 @@ devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
if (err == -EOPNOTSUPP) { if (err == -EOPNOTSUPP) {
err = 0; err = 0;
} else if (err) { } else if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
}
} }
devl_unlock(devlink);
retry:
devlink_put(devlink);
} }
out:
if (err != -EMSGSIZE)
return err;
return msg->len; return err;
} }
const struct devlink_gen_cmd devl_gen_sb_tc_pool_bind = {
.dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one,
};
static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
unsigned int sb_index, u16 tc_index, unsigned int sb_index, u16 tc_index,
enum devlink_sb_pool_type pool_type, enum devlink_sb_pool_type pool_type,
...@@ -4851,39 +4812,24 @@ static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb, ...@@ -4851,39 +4812,24 @@ static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
return genlmsg_reply(msg, info); return genlmsg_reply(msg, info);
} }
static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_selftests_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); if (!devlink->ops->selftest_check)
struct devlink *devlink; return 0;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
if (!devlink->ops->selftest_check) {
devlink_put(devlink);
continue;
}
devl_lock(devlink); return devlink_nl_selftests_fill(msg, devlink,
err = devlink_nl_selftests_fill(msg, devlink,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh->nlmsg_seq, NLM_F_MULTI,
cb->extack); cb->extack);
devl_unlock(devlink);
if (err) {
devlink_put(devlink);
break;
}
devlink_put(devlink);
}
if (err != -EMSGSIZE)
return err;
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_selftests = {
.dump_one = devlink_nl_cmd_selftests_get_dump_one,
};
static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id, static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
enum devlink_selftest_status test_status) enum devlink_selftest_status test_status)
{ {
...@@ -5329,18 +5275,15 @@ static void devlink_param_notify(struct devlink *devlink, ...@@ -5329,18 +5275,15 @@ static void devlink_param_notify(struct devlink *devlink,
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
} }
static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_param_item *param_item; struct devlink_param_item *param_item;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink);
list_for_each_entry(param_item, &devlink->param_list, list) { list_for_each_entry(param_item, &devlink->param_list, list) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
...@@ -5354,23 +5297,19 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg, ...@@ -5354,23 +5297,19 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
if (err == -EOPNOTSUPP) { if (err == -EOPNOTSUPP) {
err = 0; err = 0;
} else if (err) { } else if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink);
}
out:
if (err != -EMSGSIZE)
return err;
return msg->len; return err;
} }
const struct devlink_gen_cmd devl_gen_param = {
.dump_one = devlink_nl_cmd_param_get_dump_one,
};
static int static int
devlink_param_type_get_from_info(struct genl_info *info, devlink_param_type_get_from_info(struct genl_info *info,
enum devlink_param_type *param_type) enum devlink_param_type *param_type)
...@@ -6034,20 +5973,20 @@ static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, ...@@ -6034,20 +5973,20 @@ static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
return err; return err;
} }
static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, static int
struct netlink_callback *cb, devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct devlink *devlink, struct netlink_callback *cb)
int *idx,
int start)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink_region *region; struct devlink_region *region;
struct devlink_port *port; struct devlink_port *port;
unsigned long port_index; unsigned long port_index;
int idx = 0;
int err; int err;
list_for_each_entry(region, &devlink->region_list, list) { list_for_each_entry(region, &devlink->region_list, list) {
if (*idx < start) { if (idx < state->idx) {
(*idx)++; idx++;
continue; continue;
} }
err = devlink_nl_region_fill(msg, devlink, err = devlink_nl_region_fill(msg, devlink,
...@@ -6055,44 +5994,28 @@ static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg, ...@@ -6055,44 +5994,28 @@ static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI, region); NLM_F_MULTI, region);
if (err) if (err) {
state->idx = idx;
return err; return err;
(*idx)++; }
idx++;
} }
xa_for_each(&devlink->ports, port_index, port) { xa_for_each(&devlink->ports, port_index, port) {
err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx, err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
start); state->idx);
if (err) if (err) {
state->idx = idx;
return err; return err;
} }
}
return 0; return 0;
} }
static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg, const struct devlink_gen_cmd devl_gen_region = {
struct netlink_callback *cb) .dump_one = devlink_nl_cmd_region_get_dump_one,
{ };
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
int idx = 0;
devl_lock(devlink);
err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
&idx, state->idx);
devl_unlock(devlink);
devlink_put(devlink);
if (err) {
state->idx = idx;
goto out;
}
}
out:
return msg->len;
}
static int devlink_nl_cmd_region_del(struct sk_buff *skb, static int devlink_nl_cmd_region_del(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
...@@ -6724,35 +6647,25 @@ static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, ...@@ -6724,35 +6647,25 @@ static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
return genlmsg_reply(msg, info); return genlmsg_reply(msg, info);
} }
static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); int err;
struct devlink *devlink;
int err = 0;
devlink_dump_for_each_instance_get(msg, state, devlink) {
devl_lock(devlink);
err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET, err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
NETLINK_CB(cb->skb).portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh->nlmsg_seq, NLM_F_MULTI,
cb->extack); cb->extack);
devl_unlock(devlink);
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
err = 0; err = 0;
else if (err) {
devlink_put(devlink);
break;
}
devlink_put(devlink);
}
if (err != -EMSGSIZE)
return err; return err;
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_info = {
.dump_one = devlink_nl_cmd_info_get_dump_one,
};
struct devlink_fmsg_item { struct devlink_fmsg_item {
struct list_head list; struct list_head list;
int attrtype; int attrtype;
...@@ -8466,18 +8379,15 @@ static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb, ...@@ -8466,18 +8379,15 @@ static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
return err; return err;
} }
static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_trap_item *trap_item; struct devlink_trap_item *trap_item;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink);
list_for_each_entry(trap_item, &devlink->trap_list, list) { list_for_each_entry(trap_item, &devlink->trap_list, list) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
...@@ -8489,20 +8399,19 @@ static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg, ...@@ -8489,20 +8399,19 @@ static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI); NLM_F_MULTI);
if (err) { if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink); return err;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_trap = {
.dump_one = devlink_nl_cmd_trap_get_dump_one,
};
static int __devlink_trap_action_set(struct devlink *devlink, static int __devlink_trap_action_set(struct devlink *devlink,
struct devlink_trap_item *trap_item, struct devlink_trap_item *trap_item,
enum devlink_trap_action trap_action, enum devlink_trap_action trap_action,
...@@ -8681,46 +8590,41 @@ static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb, ...@@ -8681,46 +8590,41 @@ static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
return err; return err;
} }
static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
u32 portid = NETLINK_CB(cb->skb).portid;
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_trap_group_item *group_item; struct devlink_trap_group_item *group_item;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink);
list_for_each_entry(group_item, &devlink->trap_group_list, list_for_each_entry(group_item, &devlink->trap_group_list, list) {
list) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
continue; continue;
} }
err = devlink_nl_trap_group_fill(msg, devlink, err = devlink_nl_trap_group_fill(msg, devlink, group_item,
group_item, cmd, DEVLINK_CMD_TRAP_GROUP_NEW,
portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI); NLM_F_MULTI);
if (err) { if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink); return err;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_trap_group = {
.dump_one = devlink_nl_cmd_trap_group_get_dump_one,
};
static int static int
__devlink_trap_group_action_set(struct devlink *devlink, __devlink_trap_group_action_set(struct devlink *devlink,
struct devlink_trap_group_item *group_item, struct devlink_trap_group_item *group_item,
...@@ -8985,46 +8889,40 @@ static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb, ...@@ -8985,46 +8889,40 @@ static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
return err; return err;
} }
static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg, static int
devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
struct devlink *devlink,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct devlink_nl_dump_state *state = devlink_dump_state(cb); struct devlink_nl_dump_state *state = devlink_dump_state(cb);
enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
u32 portid = NETLINK_CB(cb->skb).portid;
struct devlink *devlink;
int err;
devlink_dump_for_each_instance_get(msg, state, devlink) {
struct devlink_trap_policer_item *policer_item; struct devlink_trap_policer_item *policer_item;
int idx = 0; int idx = 0;
int err = 0;
devl_lock(devlink); list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
list_for_each_entry(policer_item, &devlink->trap_policer_list,
list) {
if (idx < state->idx) { if (idx < state->idx) {
idx++; idx++;
continue; continue;
} }
err = devlink_nl_trap_policer_fill(msg, devlink, err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
policer_item, cmd, DEVLINK_CMD_TRAP_POLICER_NEW,
portid, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb->nlh->nlmsg_seq,
NLM_F_MULTI); NLM_F_MULTI);
if (err) { if (err) {
devl_unlock(devlink);
devlink_put(devlink);
state->idx = idx; state->idx = idx;
goto out; break;
} }
idx++; idx++;
} }
devl_unlock(devlink);
devlink_put(devlink); return err;
}
out:
return msg->len;
} }
const struct devlink_gen_cmd devl_gen_trap_policer = {
.dump_one = devlink_nl_cmd_trap_policer_get_dump_one,
};
static int static int
devlink_trap_policer_set(struct devlink *devlink, devlink_trap_policer_set(struct devlink *devlink,
struct devlink_trap_policer_item *policer_item, struct devlink_trap_policer_item *policer_item,
...@@ -9102,14 +9000,14 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9102,14 +9000,14 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_GET, .cmd = DEVLINK_CMD_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_get_doit, .doit = devlink_nl_cmd_get_doit,
.dumpit = devlink_nl_cmd_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
.cmd = DEVLINK_CMD_PORT_GET, .cmd = DEVLINK_CMD_PORT_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_port_get_doit, .doit = devlink_nl_cmd_port_get_doit,
.dumpit = devlink_nl_cmd_port_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT, .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
...@@ -9185,14 +9083,14 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9185,14 +9083,14 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_SB_GET, .cmd = DEVLINK_CMD_SB_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_sb_get_doit, .doit = devlink_nl_cmd_sb_get_doit,
.dumpit = devlink_nl_cmd_sb_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
.cmd = DEVLINK_CMD_SB_POOL_GET, .cmd = DEVLINK_CMD_SB_POOL_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_sb_pool_get_doit, .doit = devlink_nl_cmd_sb_pool_get_doit,
.dumpit = devlink_nl_cmd_sb_pool_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9205,7 +9103,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9205,7 +9103,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_SB_PORT_POOL_GET, .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_sb_port_pool_get_doit, .doit = devlink_nl_cmd_sb_port_pool_get_doit,
.dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT, .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
...@@ -9220,7 +9118,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9220,7 +9118,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET, .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit, .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
.dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT, .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
...@@ -9301,7 +9199,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9301,7 +9199,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_PARAM_GET, .cmd = DEVLINK_CMD_PARAM_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_param_get_doit, .doit = devlink_nl_cmd_param_get_doit,
.dumpit = devlink_nl_cmd_param_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9329,7 +9227,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9329,7 +9227,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_REGION_GET, .cmd = DEVLINK_CMD_REGION_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_region_get_doit, .doit = devlink_nl_cmd_region_get_doit,
.dumpit = devlink_nl_cmd_region_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
}, },
{ {
...@@ -9355,7 +9253,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9355,7 +9253,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
.cmd = DEVLINK_CMD_INFO_GET, .cmd = DEVLINK_CMD_INFO_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_info_get_doit, .doit = devlink_nl_cmd_info_get_doit,
.dumpit = devlink_nl_cmd_info_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9417,7 +9315,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9417,7 +9315,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
{ {
.cmd = DEVLINK_CMD_TRAP_GET, .cmd = DEVLINK_CMD_TRAP_GET,
.doit = devlink_nl_cmd_trap_get_doit, .doit = devlink_nl_cmd_trap_get_doit,
.dumpit = devlink_nl_cmd_trap_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9428,7 +9326,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9428,7 +9326,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
{ {
.cmd = DEVLINK_CMD_TRAP_GROUP_GET, .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
.doit = devlink_nl_cmd_trap_group_get_doit, .doit = devlink_nl_cmd_trap_group_get_doit,
.dumpit = devlink_nl_cmd_trap_group_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9439,7 +9337,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9439,7 +9337,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
{ {
.cmd = DEVLINK_CMD_TRAP_POLICER_GET, .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
.doit = devlink_nl_cmd_trap_policer_get_doit, .doit = devlink_nl_cmd_trap_policer_get_doit,
.dumpit = devlink_nl_cmd_trap_policer_get_dumpit, .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
...@@ -9450,7 +9348,7 @@ const struct genl_small_ops devlink_nl_ops[56] = { ...@@ -9450,7 +9348,7 @@ const struct genl_small_ops devlink_nl_ops[56] = {
{ {
.cmd = DEVLINK_CMD_SELFTESTS_GET, .cmd = DEVLINK_CMD_SELFTESTS_GET,
.doit = devlink_nl_cmd_selftests_get_doit, .doit = devlink_nl_cmd_selftests_get_doit,
.dumpit = devlink_nl_cmd_selftests_get_dumpit .dumpit = devlink_nl_instance_iter_dump,
/* can be retrieved by unprivileged users */ /* can be retrieved by unprivileged users */
}, },
{ {
......
...@@ -179,7 +179,20 @@ static void devlink_nl_post_doit(const struct genl_split_ops *ops, ...@@ -179,7 +179,20 @@ static void devlink_nl_post_doit(const struct genl_split_ops *ops,
} }
static const struct devlink_gen_cmd *devl_gen_cmds[] = { static const struct devlink_gen_cmd *devl_gen_cmds[] = {
[DEVLINK_CMD_GET] = &devl_gen_inst,
[DEVLINK_CMD_PORT_GET] = &devl_gen_port,
[DEVLINK_CMD_SB_GET] = &devl_gen_sb,
[DEVLINK_CMD_SB_POOL_GET] = &devl_gen_sb_pool,
[DEVLINK_CMD_SB_PORT_POOL_GET] = &devl_gen_sb_port_pool,
[DEVLINK_CMD_SB_TC_POOL_BIND_GET] = &devl_gen_sb_tc_pool_bind,
[DEVLINK_CMD_PARAM_GET] = &devl_gen_param,
[DEVLINK_CMD_REGION_GET] = &devl_gen_region,
[DEVLINK_CMD_INFO_GET] = &devl_gen_info,
[DEVLINK_CMD_RATE_GET] = &devl_gen_rate_get, [DEVLINK_CMD_RATE_GET] = &devl_gen_rate_get,
[DEVLINK_CMD_TRAP_GET] = &devl_gen_trap,
[DEVLINK_CMD_TRAP_GROUP_GET] = &devl_gen_trap_group,
[DEVLINK_CMD_TRAP_POLICER_GET] = &devl_gen_trap_policer,
[DEVLINK_CMD_SELFTESTS_GET] = &devl_gen_selftests,
}; };
int devlink_nl_instance_iter_dump(struct sk_buff *msg, int devlink_nl_instance_iter_dump(struct sk_buff *msg,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment