Skip to content

Commit 043b3e2

Browse files
kuba-moodavem330
authored andcommitted
devlink: let kernel allocate region snapshot id
Currently users have to choose a free snapshot id before calling DEVLINK_CMD_REGION_NEW. This is potentially racy and inconvenient. Make the DEVLINK_ATTR_REGION_SNAPSHOT_ID optional and try to allocate id automatically. Send a message back to the caller with the snapshot info. Example use: $ devlink region new netdevsim/netdevsim1/dummy netdevsim/netdevsim1/dummy: snapshot 1 $ id=$(devlink -j region new netdevsim/netdevsim1/dummy | \ jq '.[][][][]') $ devlink region dump netdevsim/netdevsim1/dummy snapshot $id [...] $ devlink region del netdevsim/netdevsim1/dummy snapshot $id v4: - inline the notification code v3: - send the notification only once snapshot creation completed. v2: - don't wrap the line containing extack; - add a few sentences to the docs. Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent dd86fec commit 043b3e2

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

Documentation/networking/devlink/devlink-region.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ states, but see also :doc:`devlink-health`
2323
Regions may optionally support capturing a snapshot on demand via the
2424
``DEVLINK_CMD_REGION_NEW`` netlink message. A driver wishing to allow
2525
requested snapshots must implement the ``.snapshot`` callback for the region
26-
in its ``devlink_region_ops`` structure.
26+
in its ``devlink_region_ops`` structure. If snapshot id is not set in
27+
the ``DEVLINK_CMD_REGION_NEW`` request kernel will allocate one and send
28+
the snapshot information to user space.
2729

2830
example usage
2931
-------------
@@ -45,7 +47,8 @@ example usage
4547
$ devlink region del pci/0000:00:05.0/cr-space snapshot 1
4648
4749
# Request an immediate snapshot, if supported by the region
48-
$ devlink region new pci/0000:00:05.0/cr-space snapshot 5
50+
$ devlink region new pci/0000:00:05.0/cr-space
51+
pci/0000:00:05.0/cr-space: snapshot 5
4952
5053
# Dump a snapshot:
5154
$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1

net/core/devlink.c

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,6 +4086,8 @@ static int
40864086
devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
40874087
{
40884088
struct devlink *devlink = info->user_ptr[0];
4089+
struct devlink_snapshot *snapshot;
4090+
struct nlattr *snapshot_id_attr;
40894091
struct devlink_region *region;
40904092
const char *region_name;
40914093
u32 snapshot_id;
@@ -4097,11 +4099,6 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
40974099
return -EINVAL;
40984100
}
40994101

4100-
if (!info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
4101-
NL_SET_ERR_MSG_MOD(info->extack, "No snapshot id provided");
4102-
return -EINVAL;
4103-
}
4104-
41054102
region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
41064103
region = devlink_region_get_by_name(devlink, region_name);
41074104
if (!region) {
@@ -4119,16 +4116,25 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41194116
return -ENOSPC;
41204117
}
41214118

4122-
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);
41234122

4124-
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
4125-
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
4126-
return -EEXIST;
4127-
}
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+
}
41284127

4129-
err = __devlink_snapshot_id_insert(devlink, snapshot_id);
4130-
if (err)
4131-
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+
}
41324138

41334139
err = region->ops->snapshot(devlink, info->extack, &data);
41344140
if (err)
@@ -4138,13 +4144,38 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
41384144
if (err)
41394145
goto err_snapshot_create;
41404146

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+
41414168
return 0;
41424169

41434170
err_snapshot_create:
41444171
region->ops->destructor(data);
41454172
err_snapshot_capture:
41464173
__devlink_snapshot_id_decrement(devlink, snapshot_id);
41474174
return err;
4175+
4176+
err_notify:
4177+
devlink_region_snapshot_del(region, snapshot);
4178+
return err;
41484179
}
41494180

41504181
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)