Skip to content

Commit 1248dc0

Browse files
committed
Merge branch 'devlink-kernel-region-snapshot-id-allocation'
Jakub Kicinski says: ==================== devlink: kernel region snapshot id allocation currently users have to find a free snapshot id to pass to the kernel when they are requesting a snapshot to be taken. This set extends the kernel so it can allocate the id on its own and send it back to user space in a response. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 39d0105 + aebbd7d commit 1248dc0

File tree

3 files changed

+94
-26
lines changed

3 files changed

+94
-26
lines changed

Documentation/networking/devlink/devlink-region.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Region snapshots are collected by the driver, and can be accessed via read
1414
or dump commands. This allows future analysis on the created snapshots.
1515
Regions may optionally support triggering snapshots on demand.
1616

17+
Snapshot identifiers are scoped to the devlink instance, not a region.
18+
All snapshots with the same snapshot id within a devlink instance
19+
correspond to the same event.
20+
1721
The major benefit to creating a region is to provide access to internal
1822
address regions that are otherwise inaccessible to the user.
1923

@@ -23,7 +27,9 @@ states, but see also :doc:`devlink-health`
2327
Regions may optionally support capturing a snapshot on demand via the
2428
``DEVLINK_CMD_REGION_NEW`` netlink message. A driver wishing to allow
2529
requested snapshots must implement the ``.snapshot`` callback for the region
26-
in its ``devlink_region_ops`` structure.
30+
in its ``devlink_region_ops`` structure. If snapshot id is not set in
31+
the ``DEVLINK_CMD_REGION_NEW`` request kernel will allocate one and send
32+
the snapshot information to user space.
2733

2834
example usage
2935
-------------
@@ -45,7 +51,8 @@ example usage
4551
$ devlink region del pci/0000:00:05.0/cr-space snapshot 1
4652
4753
# Request an immediate snapshot, if supported by the region
48-
$ devlink region new pci/0000:00:05.0/cr-space snapshot 5
54+
$ devlink region new pci/0000:00:05.0/cr-space
55+
pci/0000:00:05.0/cr-space: snapshot 5
4956
5057
# Dump a snapshot:
5158
$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1

net/core/devlink.c

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3716,24 +3716,26 @@ static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
37163716
return err;
37173717
}
37183718

3719-
static void devlink_nl_region_notify(struct devlink_region *region,
3720-
struct devlink_snapshot *snapshot,
3721-
enum devlink_command cmd)
3719+
static struct sk_buff *
3720+
devlink_nl_region_notify_build(struct devlink_region *region,
3721+
struct devlink_snapshot *snapshot,
3722+
enum devlink_command cmd, u32 portid, u32 seq)
37223723
{
37233724
struct devlink *devlink = region->devlink;
37243725
struct sk_buff *msg;
37253726
void *hdr;
37263727
int err;
37273728

3728-
WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
37293729

37303730
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
37313731
if (!msg)
3732-
return;
3732+
return ERR_PTR(-ENOMEM);
37333733

3734-
hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3735-
if (!hdr)
3734+
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
3735+
if (!hdr) {
3736+
err = -EMSGSIZE;
37363737
goto out_free_msg;
3738+
}
37373739

37383740
err = devlink_nl_put_handle(msg, devlink);
37393741
if (err)
@@ -3757,15 +3759,30 @@ static void devlink_nl_region_notify(struct devlink_region *region,
37573759
}
37583760
genlmsg_end(msg, hdr);
37593761

3760-
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3761-
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3762-
3763-
return;
3762+
return msg;
37643763

37653764
out_cancel_msg:
37663765
genlmsg_cancel(msg, hdr);
37673766
out_free_msg:
37683767
nlmsg_free(msg);
3768+
return ERR_PTR(err);
3769+
}
3770+
3771+
static void devlink_nl_region_notify(struct devlink_region *region,
3772+
struct devlink_snapshot *snapshot,
3773+
enum devlink_command cmd)
3774+
{
3775+
struct devlink *devlink = region->devlink;
3776+
struct sk_buff *msg;
3777+
3778+
WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3779+
3780+
msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
3781+
if (IS_ERR(msg))
3782+
return;
3783+
3784+
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3785+
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
37693786
}
37703787

37713788
/**
@@ -4069,6 +4086,8 @@ static int
40694086
devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
40704087
{
40714088
struct devlink *devlink = info->user_ptr[0];
4089+
struct devlink_snapshot *snapshot;
4090+
struct nlattr *snapshot_id_attr;
40724091
struct devlink_region *region;
40734092
const char *region_name;
40744093
u32 snapshot_id;
@@ -4080,11 +4099,6 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
40804099
return -EINVAL;
40814100
}
40824101

4083-
if (!info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
4084-
NL_SET_ERR_MSG_MOD(info->extack, "No snapshot id provided");
4085-
return -EINVAL;
4086-
}
4087-
40884102
region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
40894103
region = devlink_region_get_by_name(devlink, region_name);
40904104
if (!region) {
@@ -4102,16 +4116,25 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41024116
return -ENOSPC;
41034117
}
41044118

4105-
snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
4119+
snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
4120+
if (snapshot_id_attr) {
4121+
snapshot_id = nla_get_u32(snapshot_id_attr);
41064122

4107-
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4108-
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4109-
return -EEXIST;
4110-
}
4123+
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4124+
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4125+
return -EEXIST;
4126+
}
41114127

4112-
err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4113-
if (err)
4114-
return err;
4128+
err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4129+
if (err)
4130+
return err;
4131+
} else {
4132+
err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
4133+
if (err) {
4134+
NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
4135+
return err;
4136+
}
4137+
}
41154138

41164139
err = region->ops->snapshot(devlink, info->extack, &data);
41174140
if (err)
@@ -4121,13 +4144,38 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41214144
if (err)
41224145
goto err_snapshot_create;
41234146

4147+
if (!snapshot_id_attr) {
4148+
struct sk_buff *msg;
4149+
4150+
snapshot = devlink_region_snapshot_get_by_id(region,
4151+
snapshot_id);
4152+
if (WARN_ON(!snapshot))
4153+
return -EINVAL;
4154+
4155+
msg = devlink_nl_region_notify_build(region, snapshot,
4156+
DEVLINK_CMD_REGION_NEW,
4157+
info->snd_portid,
4158+
info->snd_seq);
4159+
err = PTR_ERR_OR_ZERO(msg);
4160+
if (err)
4161+
goto err_notify;
4162+
4163+
err = genlmsg_reply(msg, info);
4164+
if (err)
4165+
goto err_notify;
4166+
}
4167+
41244168
return 0;
41254169

41264170
err_snapshot_create:
41274171
region->ops->destructor(data);
41284172
err_snapshot_capture:
41294173
__devlink_snapshot_id_decrement(devlink, snapshot_id);
41304174
return err;
4175+
4176+
err_notify:
4177+
devlink_region_snapshot_del(region, snapshot);
4178+
return err;
41314179
}
41324180

41334181
static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,

tools/testing/selftests/drivers/net/netdevsim/devlink.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ regions_test()
151151

152152
check_region_snapshot_count dummy post-second-delete 2
153153

154+
sid=$(devlink -j region new $DL_HANDLE/dummy | jq '.[][][][]')
155+
check_err $? "Failed to create a new snapshot with id allocated by the kernel"
156+
157+
check_region_snapshot_count dummy post-first-request 3
158+
159+
devlink region dump $DL_HANDLE/dummy snapshot $sid >> /dev/null
160+
check_err $? "Failed to dump a snapshot with id allocated by the kernel"
161+
162+
devlink region del $DL_HANDLE/dummy snapshot $sid
163+
check_err $? "Failed to delete snapshot with id allocated by the kernel"
164+
165+
check_region_snapshot_count dummy post-first-request 2
166+
154167
log_test "regions test"
155168
}
156169

0 commit comments

Comments
 (0)