[PATCH 2/4] ublk: drop QUIESCE_DEV's wait for an idle command
From: Josef Bacik
Date: Tue Oct 06 2026 - 13:17:05 EST
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@xxxxxxxxxxxxxx>
---
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