Re: [PATCH] blk-mq: dispatch kworker to housekeeping CPU when hctx cpumask is empty

From: Aaron Tomlin

Date: Wed Oct 14 2026 - 21:28:17 EST


On Wed, Oct 14, 2026 at 09:34:04AM -1000, Tejun Heo wrote:
> Hello, Aaron.
>
> On Mon, Oct 12, 2026 at 12:06:25PM -0400, Aaron Tomlin wrote:
> > kblockd_workqueue is unique in that it is allocated as WQ_PERCPU to
> > preserve per-CPU locality for multi-queue devices.
>
> I haven't followed the earlier discussion, but if CPU locality is important
> without requiring hard per-CPU affinity, an unbound workqueue with
> non-strict "cpu" (or "smt" for core) affinity scope can provide both:
> locality by default with flexibility to migrate when needed.

Hi Tejun,

Thank you for your response.

That is an elegant solution. Moving kblockd_workqueue to an unbound
workqueue with a non-strict "cpu" affinity scope (WQ_AFFN_CPU) would
preserve the per-CPU/per-queue locality essential for multi-queue devices
by default, while delegating CPU isolation natively to workqueue core via
wq_unbound_cpumask. It would ultimately eliminate the need for blk-mq to
maintain ad-hoc cpumask filtering or manual housekeeping redirection.

The rationale behind the current patch is strictly as a targeted, low-risk
bugfix. Commit a46c27026da1 ("blk-mq: don't schedule block kworker on
isolated CPUs") attempted to offload queue dispatch when all mapped CPUs
are isolated by falling back to WORK_CPU_UNBOUND:

/* Switch to unbound if no allowable CPUs in this hctx */
if (hctx->queue->nr_hw_queues == 1 || blk_mq_hctx_empty_cpumask(hctx))
return WORK_CPU_UNBOUND;

However, because kblockd_workqueue is presently WQ_PERCPU, WORK_CPU_UNBOUND
resolves straight to raw_smp_processor_id(). When deferred dispatch is
triggered from an isolated core, the kworker is scheduled locally, where it
faces severe priority inversion and starvation against SCHED_FIFO
workloads.

Given that commit a46c27026da1 was backported to stable kernels, this
minimal change serves as an immediate fix suitable for stable trees without
altering the concurrency and execution semantics of kblockd across the rest
of the block layer.

That said, I would be very keen to explore transitioning kblockd_workqueue
to an unbound workqueue with non-strict CPU affinity as a follow-up series.


Kind regards,
--
Aaron Tomlin