@@ -3236,6 +3236,58 @@ static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3236
3236
return err ;
3237
3237
}
3238
3238
3239
+ static void devlink_nl_region_notify (struct devlink_region * region ,
3240
+ struct devlink_snapshot * snapshot ,
3241
+ enum devlink_command cmd )
3242
+ {
3243
+ struct devlink * devlink = region -> devlink ;
3244
+ struct sk_buff * msg ;
3245
+ void * hdr ;
3246
+ int err ;
3247
+
3248
+ WARN_ON (cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL );
3249
+
3250
+ msg = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
3251
+ if (!msg )
3252
+ return ;
3253
+
3254
+ hdr = genlmsg_put (msg , 0 , 0 , & devlink_nl_family , 0 , cmd );
3255
+ if (!hdr )
3256
+ goto out_free_msg ;
3257
+
3258
+ err = devlink_nl_put_handle (msg , devlink );
3259
+ if (err )
3260
+ goto out_cancel_msg ;
3261
+
3262
+ err = nla_put_string (msg , DEVLINK_ATTR_REGION_NAME ,
3263
+ region -> name );
3264
+ if (err )
3265
+ goto out_cancel_msg ;
3266
+
3267
+ if (snapshot ) {
3268
+ err = nla_put_u32 (msg , DEVLINK_ATTR_REGION_SNAPSHOT_ID ,
3269
+ snapshot -> id );
3270
+ if (err )
3271
+ goto out_cancel_msg ;
3272
+ } else {
3273
+ err = nla_put_u64_64bit (msg , DEVLINK_ATTR_REGION_SIZE ,
3274
+ region -> size , DEVLINK_ATTR_PAD );
3275
+ if (err )
3276
+ goto out_cancel_msg ;
3277
+ }
3278
+ genlmsg_end (msg , hdr );
3279
+
3280
+ genlmsg_multicast_netns (& devlink_nl_family , devlink_net (devlink ),
3281
+ msg , 0 , DEVLINK_MCGRP_CONFIG , GFP_KERNEL );
3282
+
3283
+ return ;
3284
+
3285
+ out_cancel_msg :
3286
+ genlmsg_cancel (msg , hdr );
3287
+ out_free_msg :
3288
+ nlmsg_free (msg );
3289
+ }
3290
+
3239
3291
static int devlink_nl_cmd_region_get_doit (struct sk_buff * skb ,
3240
3292
struct genl_info * info )
3241
3293
{
@@ -3307,6 +3359,35 @@ static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3307
3359
return msg -> len ;
3308
3360
}
3309
3361
3362
+ static int devlink_nl_cmd_region_del (struct sk_buff * skb ,
3363
+ struct genl_info * info )
3364
+ {
3365
+ struct devlink * devlink = info -> user_ptr [0 ];
3366
+ struct devlink_snapshot * snapshot ;
3367
+ struct devlink_region * region ;
3368
+ const char * region_name ;
3369
+ u32 snapshot_id ;
3370
+
3371
+ if (!info -> attrs [DEVLINK_ATTR_REGION_NAME ] ||
3372
+ !info -> attrs [DEVLINK_ATTR_REGION_SNAPSHOT_ID ])
3373
+ return - EINVAL ;
3374
+
3375
+ region_name = nla_data (info -> attrs [DEVLINK_ATTR_REGION_NAME ]);
3376
+ snapshot_id = nla_get_u32 (info -> attrs [DEVLINK_ATTR_REGION_SNAPSHOT_ID ]);
3377
+
3378
+ region = devlink_region_get_by_name (devlink , region_name );
3379
+ if (!region )
3380
+ return - EINVAL ;
3381
+
3382
+ snapshot = devlink_region_snapshot_get_by_id (region , snapshot_id );
3383
+ if (!snapshot )
3384
+ return - EINVAL ;
3385
+
3386
+ devlink_nl_region_notify (region , snapshot , DEVLINK_CMD_REGION_DEL );
3387
+ devlink_region_snapshot_del (snapshot );
3388
+ return 0 ;
3389
+ }
3390
+
3310
3391
static const struct nla_policy devlink_nl_policy [DEVLINK_ATTR_MAX + 1 ] = {
3311
3392
[DEVLINK_ATTR_BUS_NAME ] = { .type = NLA_NUL_STRING },
3312
3393
[DEVLINK_ATTR_DEV_NAME ] = { .type = NLA_NUL_STRING },
@@ -3331,6 +3412,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
3331
3412
[DEVLINK_ATTR_PARAM_TYPE ] = { .type = NLA_U8 },
3332
3413
[DEVLINK_ATTR_PARAM_VALUE_CMODE ] = { .type = NLA_U8 },
3333
3414
[DEVLINK_ATTR_REGION_NAME ] = { .type = NLA_NUL_STRING },
3415
+ [DEVLINK_ATTR_REGION_SNAPSHOT_ID ] = { .type = NLA_U32 },
3334
3416
};
3335
3417
3336
3418
static const struct genl_ops devlink_nl_ops [] = {
@@ -3537,6 +3619,13 @@ static const struct genl_ops devlink_nl_ops[] = {
3537
3619
.flags = GENL_ADMIN_PERM ,
3538
3620
.internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK ,
3539
3621
},
3622
+ {
3623
+ .cmd = DEVLINK_CMD_REGION_DEL ,
3624
+ .doit = devlink_nl_cmd_region_del ,
3625
+ .policy = devlink_nl_policy ,
3626
+ .flags = GENL_ADMIN_PERM ,
3627
+ .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK ,
3628
+ },
3540
3629
};
3541
3630
3542
3631
static struct genl_family devlink_nl_family __ro_after_init = {
@@ -4363,6 +4452,7 @@ struct devlink_region *devlink_region_create(struct devlink *devlink,
4363
4452
region -> size = region_size ;
4364
4453
INIT_LIST_HEAD (& region -> snapshot_list );
4365
4454
list_add_tail (& region -> list , & devlink -> region_list );
4455
+ devlink_nl_region_notify (region , NULL , DEVLINK_CMD_REGION_NEW );
4366
4456
4367
4457
mutex_unlock (& devlink -> lock );
4368
4458
return region ;
@@ -4390,6 +4480,8 @@ void devlink_region_destroy(struct devlink_region *region)
4390
4480
devlink_region_snapshot_del (snapshot );
4391
4481
4392
4482
list_del (& region -> list );
4483
+
4484
+ devlink_nl_region_notify (region , NULL , DEVLINK_CMD_REGION_DEL );
4393
4485
mutex_unlock (& devlink -> lock );
4394
4486
kfree (region );
4395
4487
}
@@ -4467,6 +4559,7 @@ int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
4467
4559
4468
4560
region -> cur_snapshots ++ ;
4469
4561
4562
+ devlink_nl_region_notify (region , snapshot , DEVLINK_CMD_REGION_NEW );
4470
4563
mutex_unlock (& devlink -> lock );
4471
4564
return 0 ;
4472
4565
0 commit comments