mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
When DEVLINK_CMD_REGION_NEW is issued without a snapshot id, the kernel
allocates one with __devlink_region_snapshot_id_get(). That helper counts
the caller as a user of the id, and the caller must release this hold
once it is done.
devlink_nl_region_new_doit() never drops it. The refcount of the id goes
1 (allocation) -> 2 (snapshot created) and stays at 2. When the snapshot
is deleted the count only drops to 1, so the id is never erased from
the snapshot_ids xarray. The id then stays in use for the lifetime of
the devlink instance: requesting a snapshot with that explicit id fails
with -EEXIST, and there is no snapshot left to delete to clean it up.
Reproducer steps:
# devlink region new pci/0000:13:00.0/device-caps
pci/0000:13:00.0/device-caps: snapshot 0
# devlink region del pci/0000:13:00.0/device-caps snapshot 0
# devlink region new pci/0000:13:00.0/device-caps snapshot 0
kernel answers: File exists
Drop the caller's reference right after the snapshot has been created,
as the snapshot then holds its own.
Fixes:
|
||
|---|---|---|
| .. | ||
| core.c | ||
| dev.c | ||
| devl_internal.h | ||
| dpipe.c | ||
| health.c | ||
| linecard.c | ||
| Makefile | ||
| netlink_gen.c | ||
| netlink_gen.h | ||
| netlink.c | ||
| param.c | ||
| port.c | ||
| rate.c | ||
| region.c | ||
| resource.c | ||
| sb.c | ||
| sh_dev.c | ||
| trap.c | ||