mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-04 21:31:51 +00:00
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 <davem@davemloft.net>
This commit is contained in:
commit
1248dc00fb
3 changed files with 94 additions and 26 deletions
|
@ -14,6 +14,10 @@ Region snapshots are collected by the driver, and can be accessed via read
|
||||||
or dump commands. This allows future analysis on the created snapshots.
|
or dump commands. This allows future analysis on the created snapshots.
|
||||||
Regions may optionally support triggering snapshots on demand.
|
Regions may optionally support triggering snapshots on demand.
|
||||||
|
|
||||||
|
Snapshot identifiers are scoped to the devlink instance, not a region.
|
||||||
|
All snapshots with the same snapshot id within a devlink instance
|
||||||
|
correspond to the same event.
|
||||||
|
|
||||||
The major benefit to creating a region is to provide access to internal
|
The major benefit to creating a region is to provide access to internal
|
||||||
address regions that are otherwise inaccessible to the user.
|
address regions that are otherwise inaccessible to the user.
|
||||||
|
|
||||||
|
@ -23,7 +27,9 @@ states, but see also :doc:`devlink-health`
|
||||||
Regions may optionally support capturing a snapshot on demand via the
|
Regions may optionally support capturing a snapshot on demand via the
|
||||||
``DEVLINK_CMD_REGION_NEW`` netlink message. A driver wishing to allow
|
``DEVLINK_CMD_REGION_NEW`` netlink message. A driver wishing to allow
|
||||||
requested snapshots must implement the ``.snapshot`` callback for the region
|
requested snapshots must implement the ``.snapshot`` callback for the region
|
||||||
in its ``devlink_region_ops`` structure.
|
in its ``devlink_region_ops`` structure. If snapshot id is not set in
|
||||||
|
the ``DEVLINK_CMD_REGION_NEW`` request kernel will allocate one and send
|
||||||
|
the snapshot information to user space.
|
||||||
|
|
||||||
example usage
|
example usage
|
||||||
-------------
|
-------------
|
||||||
|
@ -45,7 +51,8 @@ example usage
|
||||||
$ devlink region del pci/0000:00:05.0/cr-space snapshot 1
|
$ devlink region del pci/0000:00:05.0/cr-space snapshot 1
|
||||||
|
|
||||||
# Request an immediate snapshot, if supported by the region
|
# Request an immediate snapshot, if supported by the region
|
||||||
$ devlink region new pci/0000:00:05.0/cr-space snapshot 5
|
$ devlink region new pci/0000:00:05.0/cr-space
|
||||||
|
pci/0000:00:05.0/cr-space: snapshot 5
|
||||||
|
|
||||||
# Dump a snapshot:
|
# Dump a snapshot:
|
||||||
$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1
|
$ devlink region dump pci/0000:00:05.0/fw-health snapshot 1
|
||||||
|
|
|
@ -3716,24 +3716,26 @@ nla_put_failure:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void devlink_nl_region_notify(struct devlink_region *region,
|
static struct sk_buff *
|
||||||
struct devlink_snapshot *snapshot,
|
devlink_nl_region_notify_build(struct devlink_region *region,
|
||||||
enum devlink_command cmd)
|
struct devlink_snapshot *snapshot,
|
||||||
|
enum devlink_command cmd, u32 portid, u32 seq)
|
||||||
{
|
{
|
||||||
struct devlink *devlink = region->devlink;
|
struct devlink *devlink = region->devlink;
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg;
|
||||||
void *hdr;
|
void *hdr;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
|
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
|
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
|
||||||
if (!hdr)
|
if (!hdr) {
|
||||||
|
err = -EMSGSIZE;
|
||||||
goto out_free_msg;
|
goto out_free_msg;
|
||||||
|
}
|
||||||
|
|
||||||
err = devlink_nl_put_handle(msg, devlink);
|
err = devlink_nl_put_handle(msg, devlink);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -3757,15 +3759,30 @@ static void devlink_nl_region_notify(struct devlink_region *region,
|
||||||
}
|
}
|
||||||
genlmsg_end(msg, hdr);
|
genlmsg_end(msg, hdr);
|
||||||
|
|
||||||
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
|
return msg;
|
||||||
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
out_cancel_msg:
|
out_cancel_msg:
|
||||||
genlmsg_cancel(msg, hdr);
|
genlmsg_cancel(msg, hdr);
|
||||||
out_free_msg:
|
out_free_msg:
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
|
return ERR_PTR(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void devlink_nl_region_notify(struct devlink_region *region,
|
||||||
|
struct devlink_snapshot *snapshot,
|
||||||
|
enum devlink_command cmd)
|
||||||
|
{
|
||||||
|
struct devlink *devlink = region->devlink;
|
||||||
|
struct sk_buff *msg;
|
||||||
|
|
||||||
|
WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
|
||||||
|
|
||||||
|
msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
|
||||||
|
if (IS_ERR(msg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
|
||||||
|
msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4069,6 +4086,8 @@ static int
|
||||||
devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
|
devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
|
||||||
{
|
{
|
||||||
struct devlink *devlink = info->user_ptr[0];
|
struct devlink *devlink = info->user_ptr[0];
|
||||||
|
struct devlink_snapshot *snapshot;
|
||||||
|
struct nlattr *snapshot_id_attr;
|
||||||
struct devlink_region *region;
|
struct devlink_region *region;
|
||||||
const char *region_name;
|
const char *region_name;
|
||||||
u32 snapshot_id;
|
u32 snapshot_id;
|
||||||
|
@ -4080,11 +4099,6 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
|
|
||||||
NL_SET_ERR_MSG_MOD(info->extack, "No snapshot id provided");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
|
region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
|
||||||
region = devlink_region_get_by_name(devlink, region_name);
|
region = devlink_region_get_by_name(devlink, region_name);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
|
@ -4102,17 +4116,26 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
|
snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
|
||||||
|
if (snapshot_id_attr) {
|
||||||
|
snapshot_id = nla_get_u32(snapshot_id_attr);
|
||||||
|
|
||||||
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
|
if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
|
||||||
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
|
NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = __devlink_snapshot_id_insert(devlink, snapshot_id);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
} else {
|
||||||
|
err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
|
||||||
|
if (err) {
|
||||||
|
NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = __devlink_snapshot_id_insert(devlink, snapshot_id);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
err = region->ops->snapshot(devlink, info->extack, &data);
|
err = region->ops->snapshot(devlink, info->extack, &data);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_snapshot_capture;
|
goto err_snapshot_capture;
|
||||||
|
@ -4121,6 +4144,27 @@ devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_snapshot_create;
|
goto err_snapshot_create;
|
||||||
|
|
||||||
|
if (!snapshot_id_attr) {
|
||||||
|
struct sk_buff *msg;
|
||||||
|
|
||||||
|
snapshot = devlink_region_snapshot_get_by_id(region,
|
||||||
|
snapshot_id);
|
||||||
|
if (WARN_ON(!snapshot))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
msg = devlink_nl_region_notify_build(region, snapshot,
|
||||||
|
DEVLINK_CMD_REGION_NEW,
|
||||||
|
info->snd_portid,
|
||||||
|
info->snd_seq);
|
||||||
|
err = PTR_ERR_OR_ZERO(msg);
|
||||||
|
if (err)
|
||||||
|
goto err_notify;
|
||||||
|
|
||||||
|
err = genlmsg_reply(msg, info);
|
||||||
|
if (err)
|
||||||
|
goto err_notify;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_snapshot_create:
|
err_snapshot_create:
|
||||||
|
@ -4128,6 +4172,10 @@ err_snapshot_create:
|
||||||
err_snapshot_capture:
|
err_snapshot_capture:
|
||||||
__devlink_snapshot_id_decrement(devlink, snapshot_id);
|
__devlink_snapshot_id_decrement(devlink, snapshot_id);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err_notify:
|
||||||
|
devlink_region_snapshot_del(region, snapshot);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
|
static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
|
||||||
|
|
|
@ -151,6 +151,19 @@ regions_test()
|
||||||
|
|
||||||
check_region_snapshot_count dummy post-second-delete 2
|
check_region_snapshot_count dummy post-second-delete 2
|
||||||
|
|
||||||
|
sid=$(devlink -j region new $DL_HANDLE/dummy | jq '.[][][][]')
|
||||||
|
check_err $? "Failed to create a new snapshot with id allocated by the kernel"
|
||||||
|
|
||||||
|
check_region_snapshot_count dummy post-first-request 3
|
||||||
|
|
||||||
|
devlink region dump $DL_HANDLE/dummy snapshot $sid >> /dev/null
|
||||||
|
check_err $? "Failed to dump a snapshot with id allocated by the kernel"
|
||||||
|
|
||||||
|
devlink region del $DL_HANDLE/dummy snapshot $sid
|
||||||
|
check_err $? "Failed to delete snapshot with id allocated by the kernel"
|
||||||
|
|
||||||
|
check_region_snapshot_count dummy post-first-request 2
|
||||||
|
|
||||||
log_test "regions test"
|
log_test "regions test"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue