@@ -3149,6 +3149,111 @@ static void devlink_param_unregister_one(struct devlink *devlink,
3149
3149
kfree (param_item );
3150
3150
}
3151
3151
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
+
3152
3257
static const struct nla_policy devlink_nl_policy [DEVLINK_ATTR_MAX + 1 ] = {
3153
3258
[DEVLINK_ATTR_BUS_NAME ] = { .type = NLA_NUL_STRING },
3154
3259
[DEVLINK_ATTR_DEV_NAME ] = { .type = NLA_NUL_STRING },
@@ -3172,6 +3277,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
3172
3277
[DEVLINK_ATTR_PARAM_NAME ] = { .type = NLA_NUL_STRING },
3173
3278
[DEVLINK_ATTR_PARAM_TYPE ] = { .type = NLA_U8 },
3174
3279
[DEVLINK_ATTR_PARAM_VALUE_CMODE ] = { .type = NLA_U8 },
3280
+ [DEVLINK_ATTR_REGION_NAME ] = { .type = NLA_NUL_STRING },
3175
3281
};
3176
3282
3177
3283
static const struct genl_ops devlink_nl_ops [] = {
@@ -3370,6 +3476,14 @@ static const struct genl_ops devlink_nl_ops[] = {
3370
3476
.flags = GENL_ADMIN_PERM ,
3371
3477
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK ,
3372
3478
},
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
+ },
3373
3487
};
3374
3488
3375
3489
static struct genl_family devlink_nl_family __ro_after_init = {
0 commit comments