mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ublk: allow a NULL io->cmd in the cancel callback
A cancel from the control path, like STOP_DEV's ublk_cancel_dev() after
dropping ub->mutex, takes the command and clears io->cmd under
cancel_lock, then completes it with io_uring_cmd_done(), which takes
uring_lock to remove it from the cancelable list. The server's io_uring
cancel runs ublk_uring_cmd_cancel_fn() under uring_lock in between:
control path cancel io_uring cancel (uring_lock)
io->cmd = NULL, CANCELED
io_uring_cmd_done()
waits for uring_lock cmd still on the list
ublk_uring_cmd_cancel_fn(cmd)
io->cmd == NULL: WARN
ublk_cancel_cmd() then sees CANCELED and leaves the command alone, so
nothing is wrong; only warn if io->cmd holds another command.
Fixes: ab03a61c66 ("ublk: have a per-io daemon instead of a per-queue daemon")
Tested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20261011063555.1142277-7-tom.leiming@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
84824afdb5
commit
4915dc0a18
|
|
@ -2896,6 +2896,7 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
|||
{
|
||||
struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
|
||||
struct ublk_queue *ubq = pdu->ubq;
|
||||
struct io_uring_cmd *cur;
|
||||
struct task_struct *task;
|
||||
struct ublk_io *io;
|
||||
|
||||
|
|
@ -2912,7 +2913,9 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
|
|||
|
||||
ublk_start_cancel(ubq->dev);
|
||||
|
||||
WARN_ON_ONCE(io->cmd != cmd);
|
||||
/* NULL if a cancel from the control path took it meanwhile */
|
||||
cur = READ_ONCE(io->cmd);
|
||||
WARN_ON_ONCE(cur && cur != cmd);
|
||||
ublk_cancel_cmd(ubq, pdu->tag, issue_flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user