From: <shao.mingyin@zte.com.cn>
To: <tom.leiming@gmail.com>, <shuah@kernel.org>,
<linux-block@vger.kernel.org>, <linux-kselftest@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <stable@vger.kernel.org>
Subject: [PATCH 3/4] ublk: cancel commits arriving after the quiesce scan
Date: Wed, 11 Nov 2026 22:58:01 +0800 (CST) [thread overview]
Message-ID: <20261111225801025TKHDW7iZbMR4sFQAc8af5@zte.com.cn> (raw)
In-Reply-To: <202611112257529855AMDZLzg8ZmFDQ3fBstbi@zte.com.cn>
From: Shao Mingyin <shao.mingyin@zte.com.cn>
QUIESCE_DEV marks the queues canceling and cancels pending commands.
A server can still be processing an I/O when that scan passes its slot.
If it submits COMMIT_AND_FETCH_REQ afterwards, the newly published
command can remain queued without a future request to complete it.
The server waits for that completion and the device remains LIVE.
Share the cancellation claim with the command handler and use it after
processing a commit when the queue is canceling. The cancel lock and
CANCELED flag ensure that the control path and command handler cannot
complete the same command twice.
Fixes: b465ae7b2524 ("ublk: add feature UBLK_F_QUIESCE")
Cc: stable@vger.kernel.org
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
Tested on next-20261105 with CONFIG_BLK_DEV_UBLK=y in a local QEMU/KVM
VM (4 vCPUs, 4 GiB), using real ublk devices and fio. A test-only server
hook held one COMMIT across a successful quiesce, then released it.
In two runs per version, the original kernel left the device LIVE until
a second quiesce; the fixed kernel reached QUIESCED without that retry.
The paired runs used the same userspace probe and no kernel diagnostics.
The four original recovery scripts also passed twice with this change
and a separate batch SQE initialization fix, without C or driver
diagnostic instrumentation or reduced fio load.
drivers/block/ublk_drv.c | 40 ++++++++++++++++++++++++++--------------
1 file changed, 26 insertions(+), 14 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 3d322fa1b..082f105f1 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -2792,14 +2792,33 @@ static void ublk_start_cancel(struct ublk_device *ub)
ublk_put_disk(disk);
}
+static void ublk_complete_cancelled_cmd(struct ublk_queue *ubq,
+ struct ublk_io *io,
+ unsigned int issue_flags)
+{
+ struct io_uring_cmd *cmd = NULL;
+ bool done;
+
+ spin_lock(&ubq->cancel_lock);
+ done = !!(io->flags & UBLK_IO_FLAG_CANCELED);
+ if (!done) {
+ io->flags |= UBLK_IO_FLAG_CANCELED;
+ /* dependency ordered against smp_wmb() in ublk_prep_cancel() */
+ cmd = READ_ONCE(io->cmd);
+ io->cmd = NULL;
+ }
+ spin_unlock(&ubq->cancel_lock);
+
+ if (!done && cmd)
+ io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, issue_flags);
+}
+
static void ublk_cancel_cmd(struct ublk_queue *ubq, u16 tag,
unsigned int issue_flags)
{
struct ublk_io *io = &ubq->ios[tag];
struct ublk_device *ub = ubq->dev;
- struct io_uring_cmd *cmd = NULL;
struct request *req;
- bool done;
if (!(io->flags & UBLK_IO_FLAG_ACTIVE))
return;
@@ -2818,18 +2837,7 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, u16 tag,
if (req && blk_mq_request_started(req) && req->tag == tag)
return;
- spin_lock(&ubq->cancel_lock);
- done = !!(io->flags & UBLK_IO_FLAG_CANCELED);
- if (!done) {
- io->flags |= UBLK_IO_FLAG_CANCELED;
- /* dependency ordered against smp_wmb() in ublk_prep_cancel() */
- cmd = READ_ONCE(io->cmd);
- io->cmd = NULL;
- }
- spin_unlock(&ubq->cancel_lock);
-
- if (!done && cmd)
- io_uring_cmd_done(cmd, UBLK_IO_RES_ABORT, issue_flags);
+ ublk_complete_cancelled_cmd(ubq, io, issue_flags);
}
/*
@@ -3560,6 +3568,10 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
req->__sector = addr;
if (compl)
__ublk_complete_rq(req, io, ublk_dev_need_map_io(ub), NULL);
+
+ /* Quiesce may have scanned this slot before this command arrived. */
+ if (unlikely(READ_ONCE(ubq->canceling)))
+ ublk_complete_cancelled_cmd(ubq, io, issue_flags);
break;
}
case UBLK_IO_NEED_GET_DATA:
next prev parent reply other threads:[~2026-11-11 14:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 14:57 [PATCH 0/4] ublk: report recovery test failures and fix the exposed defects shao.mingyin
2026-11-11 14:57 ` [PATCH 1/4] selftests: ublk: propagate recovery worker failures shao.mingyin
2026-11-11 14:57 ` [PATCH 2/4] selftests: ublk: propagate stress " shao.mingyin
2026-11-15 2:07 ` Ming Lei
2026-11-15 2:28 ` Ming Lei
2026-11-11 14:58 ` shao.mingyin [this message]
2026-11-15 2:25 ` [PATCH 3/4] ublk: cancel commits arriving after the quiesce scan Ming Lei
2026-11-11 14:58 ` [PATCH 4/4] selftests: ublk: clear reused batch SQE command flags shao.mingyin
2026-11-15 2:29 ` Ming Lei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261111225801025TKHDW7iZbMR4sFQAc8af5@zte.com.cn \
--to=shao.mingyin@zte.com.cn \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tom.leiming@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®