From afc1de47a7ab607ae6403c4bfda36b0bf3cd342f Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 20 Oct 2026 05:51:29 -0700 Subject: [PATCH] blk-mq: clear stale inactive flag on hctx reuse When the last CPU mapped to an hctx goes offline, blk_mq_hctx_notify_offline() sets BLK_MQ_S_INACTIVE. Updating the number of hardware queues exits every hctx and parks it on q->unused_hctx_list. A later update can reuse a parked hctx through blk_mq_alloc_and_init_hctx(), at any queue index, and nothing clears the flag. If the reused hctx is mapped to an online CPU, blk_mq_get_tag() keeps returning BLK_MQ_NO_TAG for it. __blk_mq_alloc_requests() sleeps and retries, expecting CPU hotplug to move the task to another CPU, so a task that stays on that CPU never gets a tag. Onlining the original CPU doesn't recover it either, because blk_mq_hctx_notify_online() only clears the flag on the hctx that CPU now maps to. Clear BLK_MQ_S_INACTIVE in blk_mq_init_hctx() so a reused hctx starts like a freshly allocated one. A reused hctx has no cpuhp instances at that point, so the offline callback can't set the flag again before blk_mq_add_hw_queues_cpuhp() registers it. Clearing the flag in blk_mq_exit_hctx() is not enough, because a parked hctx keeps its cpuhp instances until blk_mq_remove_hw_queues_cpuhp(). Preserve the other hctx state flags. Reproduced with null_blk on v7.3 in a four-vCPU arm64 QEMU/KVM guest: modprobe null_blk nr_devices=0 mkdir /sys/kernel/config/nullb/nullb0 cd /sys/kernel/config/nullb/nullb0 echo 4 > submit_queues; echo 1 > memory_backed; echo 16 > size echo 1 > power echo 0 > /sys/devices/system/cpu/cpu3/online echo 2 > submit_queues echo 4 > submit_queues Offlining CPU3 marks hctx3 inactive. After the two updates it comes back as hctx1 and is mapped to CPU0: # cat /sys/block/nullb0/mq/1/cpu_list 0 # cat /sys/kernel/debug/block/nullb0/hctx1/state INACTIVE A 4K O_DIRECT read pinned to CPU0 hangs in D state, while the same read on CPU1 and CPU2 completes. Onlining CPU3 again leaves hctx1 inactive and the CPU0 read still hangs. With this change hctx1 state is empty and the reads on CPU0, CPU1 and CPU2 complete, before and after onlining CPU3. Fixes: bf0beec0607d ("blk-mq: drain I/O when all CPUs in a hctx are offline") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Nirmoy Das Link: https://patch.msgid.link/20261020125129.430600-1-nirmoyd@nvidia.com Signed-off-by: Jens Axboe --- block/blk-mq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/blk-mq.c b/block/blk-mq.c index b264e4d0a778..045be474e83d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3992,6 +3992,7 @@ static int blk_mq_init_hctx(struct request_queue *q, goto fail; hctx->queue_num = hctx_idx; + clear_bit(BLK_MQ_S_INACTIVE, &hctx->state); hctx->tags = set->tags[hctx_idx];