devlink: Add port param get command
Add port param get command which gets data per parameter. It also has option to dump the parameters data per port. v7->v8: Append "Acked-by: Jiri Pirko <jiri@mellanox.com>" Cc: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
39e6160e14
Коммит
f4601dee25
|
@ -89,6 +89,8 @@ enum devlink_command {
|
||||||
DEVLINK_CMD_REGION_DEL,
|
DEVLINK_CMD_REGION_DEL,
|
||||||
DEVLINK_CMD_REGION_READ,
|
DEVLINK_CMD_REGION_READ,
|
||||||
|
|
||||||
|
DEVLINK_CMD_PORT_PARAM_GET, /* can dump */
|
||||||
|
|
||||||
/* add new commands above here */
|
/* add new commands above here */
|
||||||
__DEVLINK_CMD_MAX,
|
__DEVLINK_CMD_MAX,
|
||||||
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
||||||
|
|
|
@ -2843,6 +2843,7 @@ nla_put_failure:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
|
static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||||
|
unsigned int port_index,
|
||||||
struct devlink_param_item *param_item,
|
struct devlink_param_item *param_item,
|
||||||
enum devlink_command cmd,
|
enum devlink_command cmd,
|
||||||
u32 portid, u32 seq, int flags)
|
u32 portid, u32 seq, int flags)
|
||||||
|
@ -2880,6 +2881,11 @@ static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||||
|
|
||||||
if (devlink_nl_put_handle(msg, devlink))
|
if (devlink_nl_put_handle(msg, devlink))
|
||||||
goto genlmsg_cancel;
|
goto genlmsg_cancel;
|
||||||
|
|
||||||
|
if (cmd == DEVLINK_CMD_PORT_PARAM_GET)
|
||||||
|
if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
|
||||||
|
goto genlmsg_cancel;
|
||||||
|
|
||||||
param_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM);
|
param_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM);
|
||||||
if (!param_attr)
|
if (!param_attr)
|
||||||
goto genlmsg_cancel;
|
goto genlmsg_cancel;
|
||||||
|
@ -2933,7 +2939,7 @@ static void devlink_param_notify(struct devlink *devlink,
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
err = devlink_nl_param_fill(msg, devlink, param_item, cmd, 0, 0, 0);
|
err = devlink_nl_param_fill(msg, devlink, 0, param_item, cmd, 0, 0, 0);
|
||||||
if (err) {
|
if (err) {
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
return;
|
return;
|
||||||
|
@ -2962,7 +2968,7 @@ static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
|
||||||
idx++;
|
idx++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
err = devlink_nl_param_fill(msg, devlink, param_item,
|
err = devlink_nl_param_fill(msg, devlink, 0, param_item,
|
||||||
DEVLINK_CMD_PARAM_GET,
|
DEVLINK_CMD_PARAM_GET,
|
||||||
NETLINK_CB(cb->skb).portid,
|
NETLINK_CB(cb->skb).portid,
|
||||||
cb->nlh->nlmsg_seq,
|
cb->nlh->nlmsg_seq,
|
||||||
|
@ -3051,7 +3057,7 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct devlink_param_item *
|
static struct devlink_param_item *
|
||||||
devlink_param_get_from_info(struct devlink *devlink,
|
devlink_param_get_from_info(struct list_head *param_list,
|
||||||
struct genl_info *info)
|
struct genl_info *info)
|
||||||
{
|
{
|
||||||
char *param_name;
|
char *param_name;
|
||||||
|
@ -3060,7 +3066,7 @@ devlink_param_get_from_info(struct devlink *devlink,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
|
param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
|
||||||
return devlink_param_find_by_name(&devlink->param_list, param_name);
|
return devlink_param_find_by_name(param_list, param_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
|
static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
|
||||||
|
@ -3071,7 +3077,7 @@ static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
param_item = devlink_param_get_from_info(devlink, info);
|
param_item = devlink_param_get_from_info(&devlink->param_list, info);
|
||||||
if (!param_item)
|
if (!param_item)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -3079,7 +3085,7 @@ static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
err = devlink_nl_param_fill(msg, devlink, param_item,
|
err = devlink_nl_param_fill(msg, devlink, 0, param_item,
|
||||||
DEVLINK_CMD_PARAM_GET,
|
DEVLINK_CMD_PARAM_GET,
|
||||||
info->snd_portid, info->snd_seq, 0);
|
info->snd_portid, info->snd_seq, 0);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -3102,7 +3108,7 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
|
||||||
union devlink_param_value value;
|
union devlink_param_value value;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
param_item = devlink_param_get_from_info(devlink, info);
|
param_item = devlink_param_get_from_info(&devlink->param_list, info);
|
||||||
if (!param_item)
|
if (!param_item)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
param = param_item->param;
|
param = param_item->param;
|
||||||
|
@ -3183,6 +3189,80 @@ static void devlink_param_unregister_one(struct devlink *devlink,
|
||||||
kfree(param_item);
|
kfree(param_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
|
||||||
|
struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct devlink_param_item *param_item;
|
||||||
|
struct devlink_port *devlink_port;
|
||||||
|
struct devlink *devlink;
|
||||||
|
int start = cb->args[0];
|
||||||
|
int idx = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&devlink_mutex);
|
||||||
|
list_for_each_entry(devlink, &devlink_list, list) {
|
||||||
|
if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
|
||||||
|
continue;
|
||||||
|
mutex_lock(&devlink->lock);
|
||||||
|
list_for_each_entry(devlink_port, &devlink->port_list, list) {
|
||||||
|
list_for_each_entry(param_item,
|
||||||
|
&devlink_port->param_list, list) {
|
||||||
|
if (idx < start) {
|
||||||
|
idx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
err = devlink_nl_param_fill(msg,
|
||||||
|
devlink_port->devlink,
|
||||||
|
devlink_port->index, param_item,
|
||||||
|
DEVLINK_CMD_PORT_PARAM_GET,
|
||||||
|
NETLINK_CB(cb->skb).portid,
|
||||||
|
cb->nlh->nlmsg_seq,
|
||||||
|
NLM_F_MULTI);
|
||||||
|
if (err) {
|
||||||
|
mutex_unlock(&devlink->lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&devlink->lock);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
mutex_unlock(&devlink_mutex);
|
||||||
|
|
||||||
|
cb->args[0] = idx;
|
||||||
|
return msg->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
|
||||||
|
struct genl_info *info)
|
||||||
|
{
|
||||||
|
struct devlink_port *devlink_port = info->user_ptr[0];
|
||||||
|
struct devlink_param_item *param_item;
|
||||||
|
struct sk_buff *msg;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
param_item = devlink_param_get_from_info(&devlink_port->param_list,
|
||||||
|
info);
|
||||||
|
if (!param_item)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
|
if (!msg)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
err = devlink_nl_param_fill(msg, devlink_port->devlink,
|
||||||
|
devlink_port->index, param_item,
|
||||||
|
DEVLINK_CMD_PORT_PARAM_GET,
|
||||||
|
info->snd_portid, info->snd_seq, 0);
|
||||||
|
if (err) {
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return genlmsg_reply(msg, info);
|
||||||
|
}
|
||||||
|
|
||||||
static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
|
static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
|
||||||
struct devlink *devlink,
|
struct devlink *devlink,
|
||||||
struct devlink_snapshot *snapshot)
|
struct devlink_snapshot *snapshot)
|
||||||
|
@ -3820,6 +3900,14 @@ static const struct genl_ops devlink_nl_ops[] = {
|
||||||
.flags = GENL_ADMIN_PERM,
|
.flags = GENL_ADMIN_PERM,
|
||||||
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
|
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.cmd = DEVLINK_CMD_PORT_PARAM_GET,
|
||||||
|
.doit = devlink_nl_cmd_port_param_get_doit,
|
||||||
|
.dumpit = devlink_nl_cmd_port_param_get_dumpit,
|
||||||
|
.policy = devlink_nl_policy,
|
||||||
|
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
|
||||||
|
/* can be retrieved by unprivileged users */
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.cmd = DEVLINK_CMD_REGION_GET,
|
.cmd = DEVLINK_CMD_REGION_GET,
|
||||||
.doit = devlink_nl_cmd_region_get_doit,
|
.doit = devlink_nl_cmd_region_get_doit,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче