[PATCH 0/3] block: revert avoid acquiring cpu hotplug lock in group_cpus_evenly

From: Daniel Wagner

Date: Thu Feb 26 2026 - 08:41:23 EST


The 0263f92fadbb ("lib/group_cpus.c: avoid acquiring cpu hotplug lock in
group_cpus_evenly") commit removed the CPU read lock.

The lock was removed because the nvme-pci driver reset handler attempted to
acquire the CPU read lock during CPU hotplug offlining (holds the write lock).
As a result, the block layer offline callback could not make progress because
in-flight requests were detected.

static bool blk_mq_has_request(struct request *rq, void *data)
{
struct rq_iter_data *iter_data = data;

if (rq->mq_hctx != iter_data->hctx)
return true;

iter_data->has_rq = true;
return false;
}

In order to bring back the CPU read lock, introduce an explicit handshake
protocol between the driver and the block layer. This allows the driver to
signal when it is safe to ignore any remaining pending requests.

I've tried several different approaches, like looking at the request_queue state
in blk_mq_has_request or at the request state but I could not convienced myself
that this works.

For example, when a requests is right before nvme_prep_rq in nvme_queue_rq, the
request is not yet marked as in flight nor are there any queue state checks left
in the remaining path:

static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
const struct blk_mq_queue_data *bd)
{
[...]

if (unlikely(!nvme_check_ready(&dev->ctrl, req, true)))
return nvme_fail_nonready_command(&dev->ctrl, req);

ret = nvme_prep_rq(req);
if (unlikely(ret))
return ret;
spin_lock(&nvmeq->sq_lock);
nvme_sq_copy_cmd(nvmeq, &iod->cmd);
nvme_write_sq_db(nvmeq, bd->last);
spin_unlock(&nvmeq->sq_lock);
return BLK_STS_OK;
}

Thus a check like

if (!blk_mq_request_started(rq) && blk_queue_quiesced(rq->q))

in blk_mq_has_request is not enough.

I've tested this by a hammering the system with PCI resets and CPU
onlining/offlining while generating load with fio. The original problem was
fairly simple to reproduce (wihtin a minute or so) and with this patches it
survived a whole night.

This unblocks my isolcpu work which touches group_cpus_evenly.

https://lore.kernel.org/linux-nvme/87cy7vrbc4.ffs@tglx/

Signed-off-by: Daniel Wagner <wagi@xxxxxxxxxx>
---
Daniel Wagner (3):
nvme: failover requests for inactive hctx
blk-mq: add handshake for offlinig hw queues
Revert "lib/group_cpus.c: avoid acquiring cpu hotplug lock in group_cpus_evenly"

block/blk-mq-debugfs.c | 1 +
block/blk-mq.c | 36 +++++++++++++++++++
drivers/nvme/host/core.c | 83 ++++++++++++++++++++++++++++++++++++++++++-
drivers/nvme/host/multipath.c | 43 ----------------------
drivers/nvme/host/nvme.h | 3 +-
drivers/nvme/host/pci.c | 3 ++
include/linux/blk-mq.h | 3 ++
lib/group_cpus.c | 21 +++--------
8 files changed, 132 insertions(+), 61 deletions(-)
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260226-revert-cpu-read-lock-94685007080a

Best regards,
--
Daniel Wagner <wagi@xxxxxxxxxx>