Skip to content

Commit d8db7ea

Browse files
alexveskerdavem330
authored andcommitted
devlink: Add support for region get command
Add support for DEVLINK_CMD_REGION_GET command which is used for querying for the supported DEV/REGION values of devlink devices. The support is both for doit and dumpit. Reply includes: BUS_NAME, DEVICE_NAME, REGION_NAME, REGION_SIZE Signed-off-by: Alex Vesker <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d7e5272 commit d8db7ea

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

include/uapi/linux/devlink.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ enum devlink_command {
8383
DEVLINK_CMD_PARAM_NEW,
8484
DEVLINK_CMD_PARAM_DEL,
8585

86+
DEVLINK_CMD_REGION_GET,
87+
DEVLINK_CMD_REGION_SET,
88+
8689
/* add new commands above here */
8790
__DEVLINK_CMD_MAX,
8891
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -262,6 +265,9 @@ enum devlink_attr {
262265
DEVLINK_ATTR_PARAM_VALUE_DATA, /* dynamic */
263266
DEVLINK_ATTR_PARAM_VALUE_CMODE, /* u8 */
264267

268+
DEVLINK_ATTR_REGION_NAME, /* string */
269+
DEVLINK_ATTR_REGION_SIZE, /* u64 */
270+
265271
/* add new attributes above here, update the policy in devlink.c */
266272

267273
__DEVLINK_ATTR_MAX,

net/core/devlink.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3149,6 +3149,111 @@ static void devlink_param_unregister_one(struct devlink *devlink,
31493149
kfree(param_item);
31503150
}
31513151

3152+
static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3153+
enum devlink_command cmd, u32 portid,
3154+
u32 seq, int flags,
3155+
struct devlink_region *region)
3156+
{
3157+
void *hdr;
3158+
int err;
3159+
3160+
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3161+
if (!hdr)
3162+
return -EMSGSIZE;
3163+
3164+
err = devlink_nl_put_handle(msg, devlink);
3165+
if (err)
3166+
goto nla_put_failure;
3167+
3168+
err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3169+
if (err)
3170+
goto nla_put_failure;
3171+
3172+
err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3173+
region->size,
3174+
DEVLINK_ATTR_PAD);
3175+
if (err)
3176+
goto nla_put_failure;
3177+
3178+
genlmsg_end(msg, hdr);
3179+
return 0;
3180+
3181+
nla_put_failure:
3182+
genlmsg_cancel(msg, hdr);
3183+
return err;
3184+
}
3185+
3186+
static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3187+
struct genl_info *info)
3188+
{
3189+
struct devlink *devlink = info->user_ptr[0];
3190+
struct devlink_region *region;
3191+
const char *region_name;
3192+
struct sk_buff *msg;
3193+
int err;
3194+
3195+
if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3196+
return -EINVAL;
3197+
3198+
region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3199+
region = devlink_region_get_by_name(devlink, region_name);
3200+
if (!region)
3201+
return -EINVAL;
3202+
3203+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3204+
if (!msg)
3205+
return -ENOMEM;
3206+
3207+
err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3208+
info->snd_portid, info->snd_seq, 0,
3209+
region);
3210+
if (err) {
3211+
nlmsg_free(msg);
3212+
return err;
3213+
}
3214+
3215+
return genlmsg_reply(msg, info);
3216+
}
3217+
3218+
static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3219+
struct netlink_callback *cb)
3220+
{
3221+
struct devlink_region *region;
3222+
struct devlink *devlink;
3223+
int start = cb->args[0];
3224+
int idx = 0;
3225+
int err;
3226+
3227+
mutex_lock(&devlink_mutex);
3228+
list_for_each_entry(devlink, &devlink_list, list) {
3229+
if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3230+
continue;
3231+
3232+
mutex_lock(&devlink->lock);
3233+
list_for_each_entry(region, &devlink->region_list, list) {
3234+
if (idx < start) {
3235+
idx++;
3236+
continue;
3237+
}
3238+
err = devlink_nl_region_fill(msg, devlink,
3239+
DEVLINK_CMD_REGION_GET,
3240+
NETLINK_CB(cb->skb).portid,
3241+
cb->nlh->nlmsg_seq,
3242+
NLM_F_MULTI, region);
3243+
if (err) {
3244+
mutex_unlock(&devlink->lock);
3245+
goto out;
3246+
}
3247+
idx++;
3248+
}
3249+
mutex_unlock(&devlink->lock);
3250+
}
3251+
out:
3252+
mutex_unlock(&devlink_mutex);
3253+
cb->args[0] = idx;
3254+
return msg->len;
3255+
}
3256+
31523257
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
31533258
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
31543259
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
@@ -3172,6 +3277,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
31723277
[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
31733278
[DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
31743279
[DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
3280+
[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
31753281
};
31763282

31773283
static const struct genl_ops devlink_nl_ops[] = {
@@ -3370,6 +3476,14 @@ static const struct genl_ops devlink_nl_ops[] = {
33703476
.flags = GENL_ADMIN_PERM,
33713477
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
33723478
},
3479+
{
3480+
.cmd = DEVLINK_CMD_REGION_GET,
3481+
.doit = devlink_nl_cmd_region_get_doit,
3482+
.dumpit = devlink_nl_cmd_region_get_dumpit,
3483+
.policy = devlink_nl_policy,
3484+
.flags = GENL_ADMIN_PERM,
3485+
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
3486+
},
33733487
};
33743488

33753489
static struct genl_family devlink_nl_family __ro_after_init = {

0 commit comments

Comments
 (0)