]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
blk-mq: use BLK_POLL_ONESHOT for synchronous poll completion
authorMing Lei <ming.lei@redhat.com>
Thu, 22 Jan 2026 04:28:58 +0000 (12:28 +0800)
committerJens Axboe <axboe@kernel.dk>
Thu, 22 Jan 2026 14:24:17 +0000 (07:24 -0700)
blk_execute_rq() with polling is used in kernel code paths such as
NVMe controller connect. The aggressive spinning in blk_hctx_poll()
can prevent the completion task from getting a chance to run, causing
a lockup.

The spinning with cpu_relax() doesn't yield CPU, so need_resched()
only becomes true on timer tick. This causes unnecessary spinning
while the completion task is already waiting to run.

Before commit f22ecf9c14c1, the loop would exit early because
task_is_running() was always true. After that commit removed the
check, the loop now spins until need_resched().

Fix this by using BLK_POLL_ONESHOT in blk_rq_poll_completion(). This
causes blk_hctx_poll() to poll once and return immediately, letting
the outer loop's cond_resched() yield CPU so the completion task can
run.

Fixes: f22ecf9c14c1 ("blk-mq: delete task running check in blk_hctx_poll()")
Cc: Diangang Li <lidiangang@bytedance.com>
Cc: Fengnan Chang <changfengnan@bytedance.com>
Reported-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-mq.c

index a29d8ac9d3e357aa6756b85298d93f173b22daf1..968699277c3d5a3a185e7ce8753807fb0f1e3f06 100644 (file)
@@ -1480,7 +1480,7 @@ EXPORT_SYMBOL_GPL(blk_rq_is_poll);
 static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 {
        do {
-               blk_hctx_poll(rq->q, rq->mq_hctx, NULL, 0);
+               blk_hctx_poll(rq->q, rq->mq_hctx, NULL, BLK_POLL_ONESHOT);
                cond_resched();
        } while (!completion_done(wait));
 }