From: Josef Bacik <josef@toxicpanda.com>
To: Ming Lei <tom.leiming@gmail.com>, Jens Axboe <axboe@kernel.dk>
Cc: Caleb Sander Mateos <csander@purestorage.com>,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/4] ublk: drop QUIESCE_DEV's wait for an idle command
Date: Tue, 6 Oct 2026 14:49:23 +0000 [thread overview]
Message-ID: <53d2ea1f34e03e73a1be52e9473fc6d692ec2194.1791303049.git.josef@toxicpanda.com> (raw)
In-Reply-To: <cover.1791303049.git.josef@toxicpanda.com>
ublk_wait_for_idle_io() is meant to wait until every queue has a command
whose request is not with the server, so that canceling it tells the
server about the quiesce. It never waits: blk_mq_tagset_busy_iter()
only calls ublk_count_busy_req() for started requests, and the callback
counts a request only when it is not started, so nr_busy is always 0
and every queue looks idle.
Making it count would not help either. It runs with ub->mutex held, so
a server which keeps every tag busy would hold up STOP_DEV, recovery
and its own release work for as long as the QUIESCE_DEV timeout, which
is forever by default. Drop it; nothing changes, since it never waited,
and a later patch has QUIESCE_DEV keep canceling until the server has
been told, without ub->mutex held.
The QUIESCE_DEV timeout in data[0] is unused until then.
Fixes: b465ae7b2524 ("ublk: add feature UBLK_F_QUIESCE")
Assisted-by: LLM
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
drivers/block/ublk_drv.c | 75 ----------------------------------------
1 file changed, 75 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 0bd0b95b3217..bd7126dcf92f 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -5338,80 +5338,9 @@ static int ublk_ctrl_set_size(struct ublk_device *ub, const struct ublksrv_ctrl_
return ret;
}
-struct count_busy {
- const struct ublk_queue *ubq;
- u16 nr_busy;
-};
-
-static bool ublk_count_busy_req(struct request *rq, void *data)
-{
- struct count_busy *idle = data;
-
- if (!blk_mq_request_started(rq) && rq->mq_hctx->driver_data == idle->ubq)
- idle->nr_busy += 1;
- return true;
-}
-
-/* uring_cmd is guaranteed to be active if the associated request is idle */
-static bool ubq_has_idle_io(const struct ublk_queue *ubq)
-{
- struct count_busy data = {
- .ubq = ubq,
- };
-
- blk_mq_tagset_busy_iter(&ubq->dev->tag_set, ublk_count_busy_req, &data);
- return data.nr_busy < ubq->q_depth;
-}
-
-/* Wait until each hw queue has at least one idle IO */
-static int ublk_wait_for_idle_io(struct ublk_device *ub,
- unsigned int timeout_ms)
-{
- unsigned int elapsed = 0;
- int ret;
-
- /*
- * For UBLK_F_BATCH_IO ublk server can get notified with existing
- * or new fetch command, so needn't wait any more
- */
- if (ublk_dev_support_batch_io(ub))
- return 0;
-
- while (elapsed < timeout_ms && !signal_pending(current)) {
- u16 i, queues_cancelable = 0;
-
- for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
- struct ublk_queue *ubq = ublk_get_queue(ub, i);
-
- queues_cancelable += !!ubq_has_idle_io(ubq);
- }
-
- /*
- * Each queue needs at least one active command for
- * notifying ublk server
- */
- if (queues_cancelable == ub->dev_info.nr_hw_queues)
- break;
-
- msleep(UBLK_REQUEUE_DELAY_MS);
- elapsed += UBLK_REQUEUE_DELAY_MS;
- }
-
- if (signal_pending(current))
- ret = -EINTR;
- else if (elapsed >= timeout_ms)
- ret = -EBUSY;
- else
- ret = 0;
-
- return ret;
-}
-
static int ublk_ctrl_quiesce_dev(struct ublk_device *ub,
const struct ublksrv_ctrl_cmd *header)
{
- /* zero means wait forever */
- u64 timeout_ms = header->data[0];
struct gendisk *disk;
bool live = true;
int ret = -ENODEV;
@@ -5445,10 +5374,6 @@ static int ublk_ctrl_quiesce_dev(struct ublk_device *ub,
blk_mq_unquiesce_queue(disk->queue);
mutex_unlock(&ub->cancel_mutex);
- if (!timeout_ms)
- timeout_ms = UINT_MAX;
- ret = ublk_wait_for_idle_io(ub, timeout_ms);
-
put_disk:
ublk_put_disk(disk);
unlock:
--
2.55.0
next prev parent reply other threads:[~2026-10-06 17:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20261001125422.1364260-1-tom.leiming@gmail.com>
2026-10-05 16:23 ` [PATCH] ublk: refuse to go live after an io command was canceled Josef Bacik
2026-10-06 14:14 ` Ming Lei
2026-10-05 16:23 ` [PATCH v2] " Josef Bacik
2026-10-06 16:10 ` [PATCH 0/4] ublk: fix UBLK_CMD_QUIESCE_DEV leaving commands behind Josef Bacik
2026-10-06 13:05 ` [PATCH 1/4] ublk: don't cancel commands in QUIESCE_DEV on a device that isn't live Josef Bacik
2026-10-06 14:49 ` Josef Bacik [this message]
2026-10-06 14:50 ` [PATCH 3/4] ublk: give the command back from COMMIT_AND_FETCH on a canceling queue Josef Bacik
2026-10-06 14:50 ` [PATCH 4/4] ublk: keep canceling in QUIESCE_DEV until the server's commands are taken Josef Bacik
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=53d2ea1f34e03e73a1be52e9473fc6d692ec2194.1791303049.git.josef@toxicpanda.com \
--to=josef@toxicpanda.com \
--cc=axboe@kernel.dk \
--cc=csander@purestorage.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@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®