* [PATCH v15 1/8] scsi: aacraid: use block layer helpers to calculate num of queues
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 2/8] lib/group_cpus: remove dead !SMP code Aaron Tomlin
` (10 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
The calculation of the upper limit for queues does not depend solely on
the number of online CPUs; for example, the isolcpus kernel
command-line option must also be considered.
To account for this, the block layer provides a helper function to
retrieve the maximum number of queues. Use it to set an appropriate
upper queue number limit.
This patch brings aacraid in line with the API migration initiated for
other SCSI drivers in commit 94970cfb5f10 ("scsi: use block layer
helpers to calculate num of queues").
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[atomlin: Drop "Fixes:" tag; indicate alignment with other SCSI drivers]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
drivers/scsi/aacraid/comminit.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 9bd3f5b868bc..ec165b57182d 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -469,8 +469,7 @@ void aac_define_int_mode(struct aac_dev *dev)
}
/* Don't bother allocating more MSI-X vectors than cpus */
- msi_count = min(dev->max_msix,
- (unsigned int)num_online_cpus());
+ msi_count = blk_mq_num_online_queues(dev->max_msix);
dev->max_msix = msi_count;
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v15 2/8] lib/group_cpus: remove dead !SMP code
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 1/8] scsi: aacraid: use block layer helpers to calculate num of queues Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 3/8] lib/group_cpus: Add group_mask_cpus_evenly() Aaron Tomlin
` (9 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
The core scheduler recently transitioned to compiling SMP data
structures unconditionally to reduce code complexity - see commit
cac5cefbade9 ("sched/smp: Make SMP unconditional").
In alignment with this philosophy of reducing dual-path maintenance,
this patch removes the #ifdef CONFIG_SMP guards and the dedicated !SMP
fallback logic here.
While the !SMP path provided a slightly simpler execution flow for
uniprocessor kernels (avoiding SMP-specific overhead), maintaining these
separate code paths adds unnecessary complexity and testing burden.
Removing these guards simplifies the codebase by standardizing entirely
on the SMP logic, which safely resolves to single-CPU operations on UP
configurations.
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[atomlin: Updated commit message to clarify !SMP removal context]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
lib/group_cpus.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/lib/group_cpus.c b/lib/group_cpus.c
index e6e18d7a49bb..b8d54398f88a 100644
--- a/lib/group_cpus.c
+++ b/lib/group_cpus.c
@@ -9,8 +9,6 @@
#include <linux/sort.h>
#include <linux/group_cpus.h>
-#ifdef CONFIG_SMP
-
static void grp_spread_init_one(struct cpumask *irqmsk, struct cpumask *nmsk,
unsigned int cpus_per_grp)
{
@@ -564,22 +562,4 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
*nummasks = min(nr_present + nr_others, numgrps);
return masks;
}
-#else /* CONFIG_SMP */
-struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
-{
- struct cpumask *masks;
-
- if (numgrps == 0)
- return NULL;
-
- masks = kzalloc_objs(*masks, numgrps);
- if (!masks)
- return NULL;
-
- /* assign all CPUs(cpu 0) to the 1st group only */
- cpumask_copy(&masks[0], cpu_possible_mask);
- *nummasks = 1;
- return masks;
-}
-#endif /* CONFIG_SMP */
EXPORT_SYMBOL_GPL(group_cpus_evenly);
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v15 3/8] lib/group_cpus: Add group_mask_cpus_evenly()
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 1/8] scsi: aacraid: use block layer helpers to calculate num of queues Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 2/8] lib/group_cpus: remove dead !SMP code Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 4/8] isolation: Introduce io_queue isolcpus type Aaron Tomlin
` (8 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
This commit introduces group_mask_cpus_evenly(), which allows callers to
distribute a specific CPU mask evenly across groups. It serves as a bounded
version of group_cpus_evenly().
While group_cpus_evenly() operates on the global cpu_possible_mask,
group_mask_cpus_evenly() confines the distribution strictly within the
boundaries of the caller-provided mask. It preserves the kernel's native
two-stage spreading logic-first prioritising CPUs that are physically
present (cpu_present_mask) to prevent I/O starvation, and then distributing
any remaining vectors to non-present CPUs to maintain hotplug safety.
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[atomlin:
- Added check for numgrps == 0
- Updated commit message to resolve typo
- Removed unused <linux/sched/isolation.h>
- Fix TOCTOU race by caching the provided mask
- Removed ineffective data_race() annotations around cpumask pointers
- Implemented two-stage grouping logic to prioritise physically
present CPUs, mirroring group_cpus_evenly()
- Fix division-by-zero bug by ensuring group_mask_cpus_evenly()
returns NULL instead of an empty array when evaluated against an
empty mask]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
include/linux/group_cpus.h | 3 +
lib/group_cpus.c | 110 +++++++++++++++++++++++++++++++++++++
2 files changed, 113 insertions(+)
diff --git a/include/linux/group_cpus.h b/include/linux/group_cpus.h
index 9d4e5ab6c314..defab4123a82 100644
--- a/include/linux/group_cpus.h
+++ b/include/linux/group_cpus.h
@@ -10,5 +10,8 @@
#include <linux/cpu.h>
struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks);
+struct cpumask *group_mask_cpus_evenly(unsigned int numgrps,
+ const struct cpumask *mask,
+ unsigned int *nummasks);
#endif
diff --git a/lib/group_cpus.c b/lib/group_cpus.c
index b8d54398f88a..75bd082e00bf 100644
--- a/lib/group_cpus.c
+++ b/lib/group_cpus.c
@@ -563,3 +563,113 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
return masks;
}
EXPORT_SYMBOL_GPL(group_cpus_evenly);
+
+/**
+ * group_mask_cpus_evenly - Group all CPUs evenly per NUMA/CPU locality
+ * @numgrps: number of cpumasks to create
+ * @mask: CPUs to consider for the grouping
+ * @nummasks: number of initialized cpumasks
+ *
+ * Return: cpumask array if successful, NULL otherwise. Only the CPUs
+ * marked in the mask will be considered for the grouping. And each
+ * element includes CPUs assigned to this group. nummasks contains the
+ * number of initialized masks which can be less than numgrps.
+ *
+ * Try to put close CPUs from viewpoint of CPU and NUMA locality into
+ * the same group.
+ *
+ * We guarantee in the resulting grouping that all CPUs specified in the
+ * provided mask are covered, and no same CPU is assigned to multiple
+ * groups.
+ */
+struct cpumask *group_mask_cpus_evenly(unsigned int numgrps,
+ const struct cpumask *mask,
+ unsigned int *nummasks)
+{
+ unsigned int curgrp = 0, nr_present = 0, nr_others = 0;
+ cpumask_var_t *node_to_cpumask;
+ cpumask_var_t nmsk, local_mask, npresmsk;
+ int ret = -ENOMEM;
+ struct cpumask *masks = NULL;
+
+ if (numgrps == 0)
+ return NULL;
+
+ if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
+ return NULL;
+
+ if (!zalloc_cpumask_var(&local_mask, GFP_KERNEL))
+ goto fail_nmsk;
+
+ if (!zalloc_cpumask_var(&npresmsk, GFP_KERNEL))
+ goto fail_local_mask;
+
+ node_to_cpumask = alloc_node_to_cpumask();
+ if (!node_to_cpumask)
+ goto fail_npresmsk;
+
+ masks = kzalloc_objs(*masks, numgrps);
+ if (!masks)
+ goto fail_node_to_cpumask;
+
+ build_node_to_cpumask(node_to_cpumask);
+
+ /*
+ * Create a stable snapshot of the mask. The grouping algorithm
+ * requires the CPU count to remain constant across its multiple
+ * passes. This prevents allocation failures if the caller passes a
+ * dynamic mask (e.g., cpu_online_mask) that changes concurrently.
+ */
+ cpumask_copy(local_mask, mask);
+
+ /*
+ * Grouping present CPUs first. We intersect the provided mask with
+ * cpu_present_mask to ensure that we prioritise physically
+ * available CPUs for the initial distribution.
+ */
+ cpumask_and(npresmsk, local_mask, cpu_present_mask);
+ ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
+ npresmsk, nmsk, masks);
+ if (ret < 0)
+ goto fail_node_to_cpumask;
+ nr_present = ret;
+
+ /*
+ * Allocate non-present CPUs starting from the next group to be
+ * handled. If the grouping of present CPUs already exhausted the
+ * group space, assign the non-present CPUs to the already
+ * allocated out groups.
+ */
+ if (nr_present >= numgrps)
+ curgrp = 0;
+ else
+ curgrp = nr_present;
+ cpumask_andnot(npresmsk, local_mask, npresmsk);
+ ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
+ npresmsk, nmsk, masks);
+ if (ret >= 0)
+ nr_others = ret;
+
+fail_node_to_cpumask:
+ free_node_to_cpumask(node_to_cpumask);
+
+fail_npresmsk:
+ free_cpumask_var(npresmsk);
+
+fail_local_mask:
+ free_cpumask_var(local_mask);
+
+fail_nmsk:
+ free_cpumask_var(nmsk);
+ if (ret < 0) {
+ kfree(masks);
+ return NULL;
+ }
+ *nummasks = min(nr_present + nr_others, numgrps);
+ if (*nummasks == 0) {
+ kfree(masks);
+ return NULL;
+ }
+ return masks;
+}
+EXPORT_SYMBOL_GPL(group_mask_cpus_evenly);
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v15 4/8] isolation: Introduce io_queue isolcpus type
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (2 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 3/8] lib/group_cpus: Add group_mask_cpus_evenly() Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled Aaron Tomlin
` (7 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
Multiqueue drivers spread I/O queues across all CPUs for optimal
performance. However, these drivers are not aware of CPU isolation
requirements and will distribute queues without considering the isolcpus
configuration.
Introduce a new isolcpus mask that allows users to define which CPUs
should have I/O queues assigned. This is similar to managed_irq, but
intended for drivers that do not use the managed IRQ infrastructure
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
include/linux/sched/isolation.h | 1 +
kernel/sched/isolation.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h
index cf0fd03dd7a2..30cb9a44365e 100644
--- a/include/linux/sched/isolation.h
+++ b/include/linux/sched/isolation.h
@@ -18,6 +18,7 @@ enum hk_type {
HK_TYPE_MANAGED_IRQ,
/* Inverse of boot-time nohz_full= or isolcpus=nohz arguments */
HK_TYPE_KERNEL_NOISE,
+ HK_TYPE_IO_QUEUE,
HK_TYPE_MAX,
/*
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index ef152d401fe2..3406e3024fd4 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -16,6 +16,7 @@ enum hk_flags {
HK_FLAG_DOMAIN = BIT(HK_TYPE_DOMAIN),
HK_FLAG_MANAGED_IRQ = BIT(HK_TYPE_MANAGED_IRQ),
HK_FLAG_KERNEL_NOISE = BIT(HK_TYPE_KERNEL_NOISE),
+ HK_FLAG_IO_QUEUE = BIT(HK_TYPE_IO_QUEUE),
};
DEFINE_STATIC_KEY_FALSE(housekeeping_overridden);
@@ -340,6 +341,12 @@ static int __init housekeeping_isolcpus_setup(char *str)
continue;
}
+ if (!strncmp(str, "io_queue,", 9)) {
+ str += 9;
+ flags |= HK_FLAG_IO_QUEUE;
+ continue;
+ }
+
/*
* Skip unknown sub-parameter and validate that it is not
* containing an invalid character.
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (3 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 4/8] isolation: Introduce io_queue isolcpus type Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-07-21 10:28 ` Marco Crivellari
2026-05-21 23:29 ` [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs Aaron Tomlin
` (6 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
Extend the capabilities of the generic CPU to hardware queue (hctx)
mapping code, so it maps houskeeping CPUs and isolated CPUs to the
hardware queues evenly.
A hctx is only operational when there is at least one online
housekeeping CPU assigned (aka active_hctx). Thus, check the final
mapping that there is no hctx which has only offline housekeeing CPU and
online isolated CPUs.
Example mapping result:
16 online CPUs
isolcpus=io_queue,2-3,6-7,12-13
Queue mapping:
hctx0: default 0 2
hctx1: default 1 3
hctx2: default 4 6
hctx3: default 5 7
hctx4: default 8 12
hctx5: default 9 13
hctx6: default 10
hctx7: default 11
hctx8: default 14
hctx9: default 15
IRQ mapping:
irq 42 affinity 0 effective 0 nvme0q0
irq 43 affinity 0 effective 0 nvme0q1
irq 44 affinity 1 effective 1 nvme0q2
irq 45 affinity 4 effective 4 nvme0q3
irq 46 affinity 5 effective 5 nvme0q4
irq 47 affinity 8 effective 8 nvme0q5
irq 48 affinity 9 effective 9 nvme0q6
irq 49 affinity 10 effective 10 nvme0q7
irq 50 affinity 11 effective 11 nvme0q8
irq 51 affinity 14 effective 14 nvme0q9
irq 52 affinity 15 effective 15 nvme0q10
A corner case is when the number of online CPUs and present CPUs
differ and the driver asks for less queues than online CPUs, e.g.
8 online CPUs, 16 possible CPUs
isolcpus=io_queue,2-3,6-7,12-13
virtio_blk.num_request_queues=2
Queue mapping:
hctx0: default 0 1 2 3 4 5 6 7 8 12 13
hctx1: default 9 10 11 14 15
IRQ mapping
irq 27 affinity 0 effective 0 virtio0-config
irq 28 affinity 0-1,4-5,8 effective 5 virtio0-req.0
irq 29 affinity 9-11,14-15 effective 0 virtio0-req.1
Noteworthy is that for the normal/default configuration (!isoclpus) the
mapping will change for systems which have non hyperthreading CPUs. The
main assignment loop will completely rely that group_mask_cpus_evenly to
do the right thing. The old code would distribute the CPUs linearly over
the hardware context:
queue mapping for /dev/nvme0n1
hctx0: default 0 8
hctx1: default 1 9
hctx2: default 2 10
hctx3: default 3 11
hctx4: default 4 12
hctx5: default 5 13
hctx6: default 6 14
hctx7: default 7 15
The assign each hardware context the map generated by the
group_mask_cpus_evenly function:
queue mapping for /dev/nvme0n1
hctx0: default 0 1
hctx1: default 2 3
hctx2: default 4 5
hctx3: default 6 7
hctx4: default 8 9
hctx5: default 10 11
hctx6: default 12 13
hctx7: default 14 15
In case of hyperthreading CPUs, the resulting map stays the same.
Signed-off-by: Daniel Wagner <wagi@kernel.org>
[atomlin:
- Updated blk_mq_validate() to use test_bit() for the new bitmap
- Replaced __free cleanups with traditional goto unwinding to align
with subsystem styling
- Updated blk_mq_map_fallback() to use qmap->queue_offset ensuring
secondary maps do not incorrectly route to the primary default map
- Added a bitmap_empty() check to prevent out-of-bounds CPU routing
when all mapped CPUs are offline
- Migrated active_hctx to a dynamically sized bitmap to fix an
out-of-bounds write when hardware queues exceed the system CPU
count
- Fixed absolute vs. relative hardware queue index mix-up in
blk_mq_map_queues() and validation checks
- Fixed typographical errors
- Reduced stack frame size of blk_mq_num_queues()
- Resolved a TOCTOU race against CPU hotplug events by snapshotting
cpu_online_mask to ensure mapping and validation phases agree
- Corrected a loop overwrite bug in blk_mq_map_queues() by iterating
directly over masks to prevent orphaned queues from being activated
- Restored topology-aware multi-queue fallback in
blk_mq_map_hw_queues() by correctly routing missing IRQ affinity
masks to the map_software path instead of the naive fallback
- Fixed a silent validation bypass in blk_mq_map_hw_queues() caused by
overlapping IRQ affinity masks by evaluating the active_hctx bitmap
in a secondary pass
- Hardened isolation logic in blk_mq_map_hw_queues() to require online
housekeeping CPUs before marking a hardware queue as active
- Enforce safe fallback of 1 when the intersection evaluates to 0]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
block/blk-mq-cpumap.c | 238 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 220 insertions(+), 18 deletions(-)
diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c
index 705da074ad6c..efb02655f59e 100644
--- a/block/blk-mq-cpumap.c
+++ b/block/blk-mq-cpumap.c
@@ -22,8 +22,15 @@ static unsigned int blk_mq_num_queues(const struct cpumask *mask,
{
unsigned int num;
- num = cpumask_weight(mask);
- return min_not_zero(num, max_queues);
+ if (housekeeping_enabled(HK_TYPE_IO_QUEUE))
+ num = cpumask_weight_and(mask, housekeeping_cpumask(HK_TYPE_IO_QUEUE));
+ else
+ num = cpumask_weight(mask);
+ /*
+ * Ensure that a count of zero does not inadvertently result in
+ * allocating the maximum number of queues.
+ */
+ return min_not_zero(num ?: 1U, max_queues);
}
/**
@@ -33,7 +40,8 @@ static unsigned int blk_mq_num_queues(const struct cpumask *mask,
* ignored.
*
* Calculates the number of queues to be used for a multiqueue
- * device based on the number of possible CPUs.
+ * device based on the number of possible CPUs. This helper
+ * takes isolcpus settings into account.
*/
unsigned int blk_mq_num_possible_queues(unsigned int max_queues)
{
@@ -48,7 +56,8 @@ EXPORT_SYMBOL_GPL(blk_mq_num_possible_queues);
* ignored.
*
* Calculates the number of queues to be used for a multiqueue
- * device based on the number of online CPUs.
+ * device based on the number of online CPUs. This helper
+ * takes isolcpus settings into account.
*/
unsigned int blk_mq_num_online_queues(unsigned int max_queues)
{
@@ -56,23 +65,139 @@ unsigned int blk_mq_num_online_queues(unsigned int max_queues)
}
EXPORT_SYMBOL_GPL(blk_mq_num_online_queues);
+static bool blk_mq_validate(struct blk_mq_queue_map *qmap,
+ const unsigned long *active_hctx,
+ const struct cpumask *online_mask)
+{
+ /*
+ * Verify if the mapping is usable when housekeeping
+ * configuration is enabled
+ */
+ for (int queue = 0; queue < qmap->nr_queues; queue++) {
+ int cpu;
+
+ if (test_bit(queue, active_hctx)) {
+ /*
+ * This hctx has at least one online CPU thus it
+ * is able to serve any assigned isolated CPU.
+ */
+ continue;
+ }
+
+ /*
+ * There is no housekeeping online CPU for this hctx, all
+ * good as long as all non-housekeeping CPUs are also
+ * offline.
+ */
+ for_each_cpu(cpu, online_mask) {
+ if (qmap->mq_map[cpu] != qmap->queue_offset + queue)
+ continue;
+
+ pr_warn("Unable to create a usable CPU-to-queue mapping with the given constraints\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void blk_mq_map_fallback(struct blk_mq_queue_map *qmap)
+{
+ unsigned int cpu;
+
+ /*
+ * Map all CPUs to the first hctx of this specific map to ensure
+ * at least one online CPU is serving it, respecting the map's
+ * boundaries so secondary maps do not route into the default map.
+ */
+ for_each_possible_cpu(cpu)
+ qmap->mq_map[cpu] = qmap->queue_offset;
+}
+
void blk_mq_map_queues(struct blk_mq_queue_map *qmap)
{
- const struct cpumask *masks;
+ struct cpumask *masks;
+ const struct cpumask *constraint;
unsigned int queue, cpu, nr_masks;
+ unsigned long *active_hctx;
+ cpumask_var_t online_mask;
- masks = group_cpus_evenly(qmap->nr_queues, &nr_masks);
- if (!masks) {
- for_each_possible_cpu(cpu)
- qmap->mq_map[cpu] = qmap->queue_offset;
- return;
- }
+ active_hctx = bitmap_zalloc(qmap->nr_queues, GFP_KERNEL);
+ if (!active_hctx)
+ goto fallback;
- for (queue = 0; queue < qmap->nr_queues; queue++) {
- for_each_cpu(cpu, &masks[queue % nr_masks])
+ if (!alloc_cpumask_var(&online_mask, GFP_KERNEL))
+ goto free_fallback_hctx;
+
+ /*
+ * Snapshot online CPUs to prevent TOCTOU races between the
+ * mapping phase and the validation phase.
+ */
+ cpumask_copy(online_mask, cpu_online_mask);
+
+ if (housekeeping_enabled(HK_TYPE_IO_QUEUE))
+ constraint = housekeeping_cpumask(HK_TYPE_IO_QUEUE);
+ else
+ constraint = cpu_possible_mask;
+
+ /* Map CPUs to the hardware contexts (hctx) */
+ masks = group_mask_cpus_evenly(qmap->nr_queues, constraint, &nr_masks);
+ if (!masks)
+ goto free_fallback;
+
+ /*
+ * Iterate directly over the generated CPU masks.
+ * Calculate the final, highest hardware queue index that maps to this
+ * mask. This skips all intermediate overwrites and safely evaluates
+ * active_hctx only for queues that survive the mapping.
+ */
+ for (unsigned int idx = 0; idx < nr_masks; idx++) {
+ bool active = false;
+ queue = qmap->nr_queues - 1 -
+ ((qmap->nr_queues - 1 - idx) % nr_masks);
+
+ for_each_cpu(cpu, &masks[idx]) {
qmap->mq_map[cpu] = qmap->queue_offset + queue;
+
+ if (!active && cpumask_test_cpu(cpu, online_mask)) {
+ __set_bit(queue, active_hctx);
+ active = true;
+ }
+ }
+ }
+
+ /*
+ * If all CPUs in the generated masks are offline, the active_hctx
+ * bitmap will be empty. Attempting to route unassigned CPUs to an
+ * empty bitmap will map them out-of-bounds. Fall back instead.
+ */
+ if (bitmap_empty(active_hctx, qmap->nr_queues))
+ goto free_fallback;
+
+ /* Map any unassigned CPU evenly to the hardware contexts (hctx) */
+ queue = find_first_bit(active_hctx, qmap->nr_queues);
+ for_each_cpu_andnot(cpu, cpu_possible_mask, constraint) {
+ qmap->mq_map[cpu] = qmap->queue_offset + queue;
+ queue = find_next_bit_wrap(active_hctx, qmap->nr_queues, queue + 1);
}
+
+ if (!blk_mq_validate(qmap, active_hctx, online_mask))
+ goto free_fallback;
+
kfree(masks);
+ free_cpumask_var(online_mask);
+ bitmap_free(active_hctx);
+
+ return;
+
+free_fallback:
+ kfree(masks);
+ free_cpumask_var(online_mask);
+free_fallback_hctx:
+ bitmap_free(active_hctx);
+
+fallback:
+ blk_mq_map_fallback(qmap);
}
EXPORT_SYMBOL_GPL(blk_mq_map_queues);
@@ -109,24 +234,101 @@ void blk_mq_map_hw_queues(struct blk_mq_queue_map *qmap,
struct device *dev, unsigned int offset)
{
- const struct cpumask *mask;
+ cpumask_var_t mask, online_mask;
+ const struct cpumask *constraint;
+ unsigned long *active_hctx;
unsigned int queue, cpu;
if (!dev->bus->irq_get_affinity)
+ goto map_software;
+
+ active_hctx = bitmap_zalloc(qmap->nr_queues, GFP_KERNEL);
+ if (!active_hctx)
+ goto fallback;
+
+ if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
+ bitmap_free(active_hctx);
goto fallback;
+ }
+
+ if (!alloc_cpumask_var(&online_mask, GFP_KERNEL))
+ goto free_fallback_mask;
+
+ if (housekeeping_enabled(HK_TYPE_IO_QUEUE))
+ constraint = housekeeping_cpumask(HK_TYPE_IO_QUEUE);
+ else
+ constraint = cpu_possible_mask;
+ /*
+ * Snapshot online CPUs to prevent TOCTOU races between the
+ * mapping phase and the validation phase.
+ */
+ cpumask_copy(online_mask, cpu_online_mask);
+
+ /* Map CPUs to the hardware contexts (hctx) */
for (queue = 0; queue < qmap->nr_queues; queue++) {
- mask = dev->bus->irq_get_affinity(dev, queue + offset);
- if (!mask)
- goto fallback;
+ const struct cpumask *affinity_mask;
+
+ affinity_mask = dev->bus->irq_get_affinity(dev, offset + queue);
+ if (!affinity_mask)
+ goto free_map_software;
- for_each_cpu(cpu, mask)
+ for_each_cpu(cpu, affinity_mask) {
qmap->mq_map[cpu] = qmap->queue_offset + queue;
+ cpumask_set_cpu(cpu, mask);
+ }
+ }
+
+ /*
+ * Evaluate active_hctx after mapping to handle overlapping masks.
+ * This ensures queues that were overwritten do not falsely pass validation.
+ */
+ for_each_cpu(cpu, mask) {
+ if (cpumask_test_cpu(cpu, online_mask) &&
+ cpumask_test_cpu(cpu, constraint)) {
+ queue = qmap->mq_map[cpu] - qmap->queue_offset;
+ __set_bit(queue, active_hctx);
+ }
+ }
+
+ /*
+ * If all CPUs assigned to this map are offline, the bitmap will
+ * be empty. Fall back instead of routing out of bounds.
+ */
+ if (bitmap_empty(active_hctx, qmap->nr_queues))
+ goto free_fallback;
+
+ /* Map any unassigned CPU evenly to the hardware contexts (hctx) */
+ queue = find_first_bit(active_hctx, qmap->nr_queues);
+ for_each_cpu_andnot(cpu, cpu_possible_mask, mask) {
+ qmap->mq_map[cpu] = qmap->queue_offset + queue;
+ queue = find_next_bit_wrap(active_hctx, qmap->nr_queues, queue + 1);
}
+ if (!blk_mq_validate(qmap, active_hctx, online_mask))
+ goto free_fallback;
+
+ bitmap_free(active_hctx);
+ free_cpumask_var(mask);
+ free_cpumask_var(online_mask);
+
return;
+free_fallback:
+ free_cpumask_var(online_mask);
+free_fallback_mask:
+ bitmap_free(active_hctx);
+ free_cpumask_var(mask);
+
fallback:
+ blk_mq_map_fallback(qmap);
+ return;
+
+free_map_software:
+ free_cpumask_var(online_mask);
+ free_cpumask_var(mask);
+ bitmap_free(active_hctx);
+map_software:
blk_mq_map_queues(qmap);
}
EXPORT_SYMBOL_GPL(blk_mq_map_hw_queues);
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled
2026-05-21 23:29 ` [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled Aaron Tomlin
@ 2026-07-21 10:28 ` Marco Crivellari
2026-08-05 19:01 ` Aaron Tomlin
0 siblings, 1 reply; 24+ messages in thread
From: Marco Crivellari @ 2026-07-21 10:28 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, rishil1999,
linux-block, linux-kernel
Hi,
On Fri, May 22, 2026 at 1:30 AM Aaron Tomlin <atomlin@atomlin.com> wrote:
> + void blk_mq_map_queues(struct blk_mq_queue_map *qmap)
> [..]
> + /*
> + * Snapshot online CPUs to prevent TOCTOU races between the
> + * mapping phase and the validation phase.
> + */
> + cpumask_copy(online_mask, cpu_online_mask);
I'm wondering: should this code be protected somehow, maybe directly
by the caller (eg w/ cpus_read_lock()) to avoid a CPU going offline eg
after the copy?
This invalidates the copy because a CPU set there might have gone
offline, and the blk code would then still use that CPU.
Does that make sense or it is not the case?
Thanks!
--
Marco Crivellari
SUSE Labs
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled
2026-07-21 10:28 ` Marco Crivellari
@ 2026-08-05 19:01 ` Aaron Tomlin
0 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-08-05 19:01 UTC (permalink / raw)
To: Marco Crivellari
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, rishil1999,
linux-block, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1945 bytes --]
On Tue, Jul 21, 2026 at 12:28:04PM +0200, Marco Crivellari wrote:
> Hi,
>
> On Fri, May 22, 2026 at 1:30 AM Aaron Tomlin <atomlin@atomlin.com> wrote:
> > + void blk_mq_map_queues(struct blk_mq_queue_map *qmap)
> > [..]
> > + /*
> > + * Snapshot online CPUs to prevent TOCTOU races between the
> > + * mapping phase and the validation phase.
> > + */
> > + cpumask_copy(online_mask, cpu_online_mask);
>
> I'm wondering: should this code be protected somehow, maybe directly
> by the caller (eg w/ cpus_read_lock()) to avoid a CPU going offline eg
> after the copy?
> This invalidates the copy because a CPU set there might have gone
> offline, and the blk code would then still use that CPU.
>
> Does that make sense or it is not the case?
>
> Thanks!
Hi Marco,
Thank you for reviewing the patch and raising this point!
Yes, taking a lockless snapshot via cpumask_copy(online_mask,
cpu_online_mask) introduces a TOCTOU race, as a CPU could go offline
immediately after the copy, leaving online_mask stale during validation.
Rather than introducing cpus_read_lock() into block/ to protect a dynamic
cpu_online_mask sample, a cleaner solution is to align blk_mq_map_queues()
with existing blk-mq architectural patterns.
1. Refactor blk_mq_map_queues() to build mappings using the static
housekeeping mask intersected with cpu_present_mask (or
cpu_possible_mask), removing the dynamic cpu_online_mask snapshot
and blk_mq_validate() check altogether
2. Rely on blk_mq_hctx_notify_offline()—introduced in patch 4/8 of
this series—to enforce runtime hotplug safety. The function
blk_mq_hctx_notify_offline() already runs under cpus_write_lock()
during CPU hotplug and explicitly prevents offlining the final
housekeeping CPU serving an active isolated CPU
Kind regards,
--
Aaron Tomlin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (4 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 5/8] blk-mq: use hk cpus only when isolcpus=io_queue is enabled Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-07-21 14:19 ` Marco Crivellari
2026-05-21 23:29 ` [PATCH v15 7/8] genirq/affinity: Restrict managed IRQ affinity to housekeeping CPUs Aaron Tomlin
` (5 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
When isolcpus=io_queue is enabled and the last housekeeping CPU
for a given hctx goes offline, no CPU would be left to handle I/O.
To prevent I/O stalls, disallow offlining housekeeping CPUs that are
still serving isolated CPUs.
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[atomlin:
- Removed duplicate paragraph from commit message
- Allow offlining of non-housekeeping CPUs
- Fix logic flaw that prematurely rejected valid offline requests
- Iterated over cpu_online_mask and manually reverse-mapped CPUs to
correctly detect isolated CPUs, as blk_mq_map_swqueue()
intentionally prunes them from hctx->cpumask
- Drop hctx->queue->disk->disk_name from warning to avoid UAF bug
- Ensure isolation constraints are only enforced for CPUs actively
mapped to the evaluated hardware queue
- Correct pr_warn format specifier]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
block/blk-mq.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d0c37daf568f..7c3f4d6546f0 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3739,6 +3739,56 @@ static bool blk_mq_hctx_has_requests(struct blk_mq_hw_ctx *hctx)
return data.has_rq;
}
+static bool blk_mq_hctx_can_offline_hk_cpu(struct blk_mq_hw_ctx *hctx,
+ unsigned int this_cpu)
+{
+ const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_IO_QUEUE);
+ int cpu, fallback_isolated_cpu = -1;
+
+ /*
+ * If the CPU being offlined is not a housekeeping CPU,
+ * offlining it will not strand isolated CPUs. Allow it.
+ */
+ if (!cpumask_test_cpu(this_cpu, hk_mask))
+ return true;
+ /*
+ * If this CPU is not mapped to this specific hardware context,
+ * offlining it will not affect the context's I/O routing. Allow it.
+ */
+ if (blk_mq_map_queue_type(hctx->queue, hctx->type, this_cpu) != hctx)
+ return true;
+ /*
+ * Iterate over all online CPUs and manually check their mapping.
+ * We cannot use hctx->cpumask here because blk_mq_map_swqueue()
+ * intentionally strips isolated CPUs from it to prevent kworker
+ * routing.
+ */
+ for_each_online_cpu(cpu) {
+ struct blk_mq_hw_ctx *h;
+
+ if (cpu == this_cpu)
+ continue;
+
+ h = blk_mq_map_queue_type(hctx->queue, hctx->type, cpu);
+ if (h != hctx)
+ continue;
+
+ if (cpumask_test_cpu(cpu, hk_mask))
+ return true;
+
+ if (fallback_isolated_cpu == -1)
+ fallback_isolated_cpu = cpu;
+ }
+
+ if (fallback_isolated_cpu != -1) {
+ pr_warn("blk-mq: trying to offline hctx%u but online isolated CPU %d is still mapped to it\n",
+ hctx->queue_num, fallback_isolated_cpu);
+ return false;
+ }
+
+ return true;
+}
+
static bool blk_mq_hctx_has_online_cpu(struct blk_mq_hw_ctx *hctx,
unsigned int this_cpu)
{
@@ -3771,6 +3821,11 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
struct blk_mq_hw_ctx, cpuhp_online);
int ret = 0;
+ if (housekeeping_enabled(HK_TYPE_IO_QUEUE)) {
+ if (!blk_mq_hctx_can_offline_hk_cpu(hctx, cpu))
+ return -EINVAL;
+ }
+
if (!hctx->nr_ctx || blk_mq_hctx_has_online_cpu(hctx, cpu))
return 0;
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs
2026-05-21 23:29 ` [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs Aaron Tomlin
@ 2026-07-21 14:19 ` Marco Crivellari
2026-08-05 19:20 ` Aaron Tomlin
0 siblings, 1 reply; 24+ messages in thread
From: Marco Crivellari @ 2026-07-21 14:19 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, rishil1999,
linux-block, linux-kernel
Hi,
On Fri, May 22, 2026 at 1:30 AM Aaron Tomlin <atomlin@atomlin.com> wrote:
> [...]
> static bool blk_mq_hctx_has_online_cpu(struct blk_mq_hw_ctx *hctx,
> unsigned int this_cpu)
> {
> @@ -3771,6 +3821,11 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
> struct blk_mq_hw_ctx, cpuhp_online);
> int ret = 0;
>
> + if (housekeeping_enabled(HK_TYPE_IO_QUEUE)) {
> + if (!blk_mq_hctx_can_offline_hk_cpu(hctx, cpu))
> + return -EINVAL;
> + }
> +
> if (!hctx->nr_ctx || blk_mq_hctx_has_online_cpu(hctx, cpu))
> return 0;
I noticed the existing `if` returns 0, while the added code returns
-EINVAL. I'm wondering if this will prevent the system from suspending
because of the -EINVAL error.
Should ` !cpuhp_tasks_frozen` be added to the if statement?
eg.
if (housekeeping_enabled(HK_TYPE_IO_QUEUE) && !cpuhp_tasks_frozen) {
if (!blk_mq_hctx_can_offline_hk_cpu(hctx, cpu))
return -EINVAL;
}
Or maybe just handling this inside blk_mq_hctx_can_offline_hk_cpu()
returning true.
Does it make sense?
Thanks!
--
Marco Crivellari
SUSE Labs
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs
2026-07-21 14:19 ` Marco Crivellari
@ 2026-08-05 19:20 ` Aaron Tomlin
0 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-08-05 19:20 UTC (permalink / raw)
To: Marco Crivellari
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, rishil1999,
linux-block, linux-kernel
On Tue, Jul 21, 2026 at 04:19:26PM +0200, Marco Crivellari wrote:
> Hi,
>
> On Fri, May 22, 2026 at 1:30 AM Aaron Tomlin <atomlin@atomlin.com> wrote:
> > [...]
> > static bool blk_mq_hctx_has_online_cpu(struct blk_mq_hw_ctx *hctx,
> > unsigned int this_cpu)
> > {
> > @@ -3771,6 +3821,11 @@ static int blk_mq_hctx_notify_offline(unsigned int cpu, struct hlist_node *node)
> > struct blk_mq_hw_ctx, cpuhp_online);
> > int ret = 0;
> >
> > + if (housekeeping_enabled(HK_TYPE_IO_QUEUE)) {
> > + if (!blk_mq_hctx_can_offline_hk_cpu(hctx, cpu))
> > + return -EINVAL;
> > + }
> > +
> > if (!hctx->nr_ctx || blk_mq_hctx_has_online_cpu(hctx, cpu))
> > return 0;
>
> I noticed the existing `if` returns 0, while the added code returns
> -EINVAL. I'm wondering if this will prevent the system from suspending
> because of the -EINVAL error.
> Should ` !cpuhp_tasks_frozen` be added to the if statement?
>
> eg.
>
> if (housekeeping_enabled(HK_TYPE_IO_QUEUE) && !cpuhp_tasks_frozen) {
> if (!blk_mq_hctx_can_offline_hk_cpu(hctx, cpu))
> return -EINVAL;
> }
>
> Or maybe just handling this inside blk_mq_hctx_can_offline_hk_cpu()
> returning true.
>
> Does it make sense?
Hi Marco,
Absolutely!
During system suspend/hibernation I/O is quiesced, and all CPUs are being
taken down for system sleep. Returning -EINVAL breaks system power
management. Offlining must be allowed to proceed.
Yes, we should test for cpuhp_tasks_frozen in
blk_mq_hctx_can_offline_hk_cpu().
Kind regards,
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v15 7/8] genirq/affinity: Restrict managed IRQ affinity to housekeeping CPUs
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (5 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 6/8] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-05-21 23:29 ` [PATCH v15 8/8] docs: add io_queue flag to isolcpus Aaron Tomlin
` (4 subsequent siblings)
11 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
At present, the managed interrupt spreading algorithm distributes vectors
across all available CPUs within a given node or system. On systems
employing CPU isolation (e.g., "isolcpus=io_queue"), this behaviour
defeats the primary purpose of isolation by routing hardware interrupts
(such as NVMe completion queues) directly to isolated cores.
Update irq_create_affinity_masks() to respect the housekeeping CPU mask.
By passing the HK_TYPE_IO_QUEUE mask directly to the topological
distribution function (group_mask_cpus_evenly()), we ensure that managed
interrupts are kept strictly off isolated CPUs.
This patch additionally addresses the architectural constraints of
restricted vector distribution:
1. Vector Limits and Overrides: Updated irq_calc_affinity_vectors()
to strictly bound the maximum number of allocated vectors to the
weight of the housekeeping mask. This correctly overrides
drivers providing a calc_sets() callback, preventing them from
wasting memory on dead hardware queues that cannot be routed to
isolated CPUs.
2. Multi-set Alignment and Leak Prevention: When isolation
constraints result in fewer available masks than requested
vectors for a given set, the remaining vector slots are padded
with the housekeeping mask. This replaces the historical
irq_default_affinity padding, ensuring excess managed queues do
not leak interrupts onto isolated CPUs.
3. Minimum Vector Safety Net: To prevent fatal -ENOSPC device probe
aborts on heavily isolated systems (where the housekeeping CPU
count might be lower than a device's structural minimum), the
final vector calculation is safeguarded to never drop below
minvec. Queues will safely share the available housekeeping CPUs
instead of failing the probe.
4. Zero Overhead: The housekeeping mask is conditionally assigned
via a direct pointer, completely avoiding temporary mask
allocations (e.g., alloc_cpumask_var) and bitwise operations
when CPU isolation is disabled. This guarantees zero performance
or memory overhead for standard configurations.
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
kernel/irq/affinity.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c
index 78f2418a8925..dade92f8b4b3 100644
--- a/kernel/irq/affinity.c
+++ b/kernel/irq/affinity.c
@@ -8,6 +8,7 @@
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/group_cpus.h>
+#include <linux/sched/isolation.h>
static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs)
{
@@ -25,8 +26,10 @@ static void default_calc_sets(struct irq_affinity *affd, unsigned int affvecs)
struct irq_affinity_desc *
irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
{
- unsigned int affvecs, curvec, usedvecs, i;
+ unsigned int affvecs, curvec, usedvecs, i, j;
struct irq_affinity_desc *masks = NULL;
+ const struct cpumask *hk_mask = housekeeping_cpumask(HK_TYPE_IO_QUEUE);
+ bool hk_enabled = housekeeping_enabled(HK_TYPE_IO_QUEUE);
/*
* Determine the number of vectors which need interrupt affinities
@@ -70,19 +73,29 @@ irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd)
*/
for (i = 0, usedvecs = 0; i < affd->nr_sets; i++) {
unsigned int nr_masks, this_vecs = affd->set_size[i];
- struct cpumask *result = group_cpus_evenly(this_vecs, &nr_masks);
+ struct cpumask *result;
+ const struct cpumask *mask;
+ if (hk_enabled)
+ mask = hk_mask;
+ else
+ mask = cpu_possible_mask;
+
+ result = group_mask_cpus_evenly(this_vecs, mask,
+ &nr_masks);
if (!result) {
kfree(masks);
return NULL;
}
-
- for (int j = 0; j < nr_masks; j++)
+ for (j = 0; j < nr_masks; j++)
cpumask_copy(&masks[curvec + j].mask, &result[j]);
+ for (j = nr_masks; j < this_vecs; j++)
+ cpumask_copy(&masks[curvec + j].mask, mask);
+
kfree(result);
- curvec += nr_masks;
- usedvecs += nr_masks;
+ curvec += this_vecs;
+ usedvecs += this_vecs;
}
/* Fill out vectors at the end that don't need affinity */
@@ -115,10 +128,12 @@ unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
if (resv > minvec)
return 0;
- if (affd->calc_sets)
+ if (housekeeping_enabled(HK_TYPE_IO_QUEUE))
+ set_vecs = cpumask_weight(housekeeping_cpumask(HK_TYPE_IO_QUEUE));
+ else if (affd->calc_sets)
set_vecs = maxvec - resv;
else
set_vecs = cpumask_weight(cpu_possible_mask);
- return resv + min(set_vecs, maxvec - resv);
+ return max(minvec, resv + min(set_vecs, maxvec - resv));
}
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH v15 8/8] docs: add io_queue flag to isolcpus
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (6 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 7/8] genirq/affinity: Restrict managed IRQ affinity to housekeeping CPUs Aaron Tomlin
@ 2026-05-21 23:29 ` Aaron Tomlin
2026-07-15 10:25 ` Sebastian Andrzej Siewior
2026-05-26 16:05 ` [PATCH v15 0/8] blk: honor isolcpus configuration Daniel Wagner
` (3 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-21 23:29 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: atomlin, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
From: Daniel Wagner <wagi@kernel.org>
The io_queue flag informs multiqueue device drivers where to place
hardware queues. Document this new flag in the isolcpus
command-line argument description.
Signed-off-by: Daniel Wagner <wagi@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
[atomlin:
- Refined io_queue kernel parameter documentation
- Removed an inaccurate claim in the documentation stating
that io_queue takes precedence over managed_irq]
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
.../admin-guide/kernel-parameters.txt | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 4d0f545fb3ec..fb828bb60b9e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2792,7 +2792,6 @@ Kernel parameters
"number of CPUs in system - 1".
managed_irq
-
Isolate from being targeted by managed interrupts
which have an interrupt mask containing isolated
CPUs. The affinity of managed interrupts is
@@ -2815,6 +2814,31 @@ Kernel parameters
housekeeping CPUs has no influence on those
queues.
+ io_queue
+ Applicable to managed IRQs only. Restrict
+ multiqueue hardware queue allocation to online
+ housekeeping CPUs. This guarantees that all
+ managed hardware completion interrupts are routed
+ exclusively to housekeeping cores, shielding
+ isolated CPUs from I/O interruptions even if they
+ initiated the request.
+
+ Note: Using io_queue restricts the number of
+ allocated hardware queues to match the number of
+ housekeeping CPUs. This prevents MSI-X vector
+ exhaustion and forces isolated CPUs to share
+ submission queues.
+
+ Note: Offlining housekeeping CPUs which serve
+ isolated CPUs will fail. The isolated CPUs must
+ be offlined before offlining the housekeeping
+ CPUs.
+
+ Note: When I/O is submitted by an application on
+ an isolated CPU, the hardware completion
+ interrupt is handled entirely by a housekeeping
+ CPU.
+
The format of <cpu-list> is described above.
iucv= [HW,NET]
--
2.51.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* Re: [PATCH v15 8/8] docs: add io_queue flag to isolcpus
2026-05-21 23:29 ` [PATCH v15 8/8] docs: add io_queue flag to isolcpus Aaron Tomlin
@ 2026-07-15 10:25 ` Sebastian Andrzej Siewior
2026-08-05 16:22 ` Aaron Tomlin
0 siblings, 1 reply; 24+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-07-15 10:25 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
On 2026-05-21 19:29:56 [-0400], Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
>
> The io_queue flag informs multiqueue device drivers where to place
> hardware queues. Document this new flag in the isolcpus
> command-line argument description.
>
> Signed-off-by: Daniel Wagner <wagi@kernel.org>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> [atomlin:
> - Refined io_queue kernel parameter documentation
> - Removed an inaccurate claim in the documentation stating
> that io_queue takes precedence over managed_irq]
> Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
From high level, this looks like managed_irq with the exception that you
can limit the number of assigned interrupts while managed_irq is best
effort. Is this true or do I oversimplify something?
If so, can this be integrated?
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 4d0f545fb3ec..fb828bb60b9e 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -2815,6 +2814,31 @@ Kernel parameters
> housekeeping CPUs has no influence on those
> queues.
>
> + io_queue
> + Applicable to managed IRQs only. Restrict
> + multiqueue hardware queue allocation to online
> + housekeeping CPUs. This guarantees that all
> + managed hardware completion interrupts are routed
> + exclusively to housekeeping cores, shielding
> + isolated CPUs from I/O interruptions even if they
> + initiated the request.
> +
> + Note: Using io_queue restricts the number of
> + allocated hardware queues to match the number of
> + housekeeping CPUs. This prevents MSI-X vector
> + exhaustion and forces isolated CPUs to share
> + submission queues.
> +
> + Note: Offlining housekeeping CPUs which serve
> + isolated CPUs will fail. The isolated CPUs must
> + be offlined before offlining the housekeeping
> + CPUs.
> +
> + Note: When I/O is submitted by an application on
> + an isolated CPU, the hardware completion
> + interrupt is handled entirely by a housekeeping
> + CPU.
This is named io_queue but it does affect I/O in general unless the
driver uses managed_irqs. This may or may not be clear to the user.
So the io_queue might not be the perfect name given that affects alles
devices in the system. We do have just I/O devices using it right now.
I think this still deserves an explanation in
Documentation/core-api/irq/managed_irq.rst like how to use it, what is
the expected outcome and how does it interact with the managed_irq
argument. Does it make sense to use both, is it exclusive or, what would
be the use case for both arguments.
> The format of <cpu-list> is described above.
>
> iucv= [HW,NET]
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 8/8] docs: add io_queue flag to isolcpus
2026-07-15 10:25 ` Sebastian Andrzej Siewior
@ 2026-08-05 16:22 ` Aaron Tomlin
2026-08-21 15:16 ` Sebastian Andrzej Siewior
0 siblings, 1 reply; 24+ messages in thread
From: Aaron Tomlin @ 2026-08-05 16:22 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
On Wed, Jul 15, 2026 at 12:25:35PM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-05-21 19:29:56 [-0400], Aaron Tomlin wrote:
> > From: Daniel Wagner <wagi@kernel.org>
> >
> > The io_queue flag informs multiqueue device drivers where to place
> > hardware queues. Document this new flag in the isolcpus
> > command-line argument description.
> >
> > Signed-off-by: Daniel Wagner <wagi@kernel.org>
> > Reviewed-by: Hannes Reinecke <hare@suse.de>
> > [atomlin:
> > - Refined io_queue kernel parameter documentation
> > - Removed an inaccurate claim in the documentation stating
> > that io_queue takes precedence over managed_irq]
> > Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
>
> From high level, this looks like managed_irq with the exception that you
> can limit the number of assigned interrupts while managed_irq is best
> effort. Is this true or do I oversimplify something?
Hi Sebastian,
Thank you for reviewing the patch set and for your feedback.
Yes. Though the underlying mechanisms differ in a fundamental way between
the two flags:
isolcpus=managed_irq (post-allocation, best-effort):
managed_irq operates downstream at the IRQ affinity level (i.e.,
kernel/irq/manage.c and kernel/irq/cpuhotplug.c). It attempts to steer
the effective affinity of already-allocated IRQ vectors away from
isolated CPUs. However, when a multiqueue storage or networking driver
allocates one hardware queue per CPU, the affinity mask for an isolated
CPU's queue contains only that specific CPU. Because the intersection
between the queue's mask and the housekeeping CPUs is empty,
managed_irq falls back to assigning the interrupt to the isolated CPU.
It is therefore inherently "best effort" and cannot guarantee isolation
for 1-queue-per-CPU devices.
isolcpus=io_queue (pre-allocation, strict constraint):
io_queue operates upstream during device probe, MSI-X vector
calculation, and block-multiqueue topology setup
(irq_calc_affinity_vectors(), irq_create_affinity_masks(), and blk-mq).
Rather than attempting to steer vectors after allocation, it caps the
total number of hardware queues and MSI-X vectors to match the weight
of the online housekeeping CPUs. Isolated CPUs are strictly excluded
during initial vector mask generation (group_mask_cpus_evenly()). I/O
requests submitted from isolated CPUs are routed through shared
submission queues mapped onto housekeeping cores, ensuring completion
interrupts land exclusively on housekeeping CPUs.
In summary, while managed_irq influences where already-created interrupts
land, io_queue restricts how many queues are created and how the hardware
topology is constructed.
I hope this helps.
> If so, can this be integrated?
I do not want managed_irq unconditionally enforced vector capping. Instead
of creating a standalone HK_TYPE_IO_QUEUE housekeeping flag, the strict
vector capping and mask restriction could be integrated under an opt-in
flag?
How about an opt-in flag:
- isolcpus=managed_irq
Keeps best-effort post-allocation IRQ steering without capping
hardware queues
- isolcpus=managed_irq_strict (or managed_irq:strict)
Enables strict pre-allocation queue capping (i.e.,
irq_calc_affinity_vectors() and blk_mq queue limits)
If the preference is to avoid adding a new top-level isolcpus= flag, I am
more than happy to refactor io_queue into a strict sub-parameter under
managed_irq (e.g., isolcpus=managed_irq:strict). This probably makes more
sense.
> > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > index 4d0f545fb3ec..fb828bb60b9e 100644
> > --- a/Documentation/admin-guide/kernel-parameters.txt
> > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > @@ -2815,6 +2814,31 @@ Kernel parameters
> > housekeeping CPUs has no influence on those
> > queues.
> >
> > + io_queue
> > + Applicable to managed IRQs only. Restrict
> > + multiqueue hardware queue allocation to online
> > + housekeeping CPUs. This guarantees that all
> > + managed hardware completion interrupts are routed
> > + exclusively to housekeeping cores, shielding
> > + isolated CPUs from I/O interruptions even if they
> > + initiated the request.
> > +
> > + Note: Using io_queue restricts the number of
> > + allocated hardware queues to match the number of
> > + housekeeping CPUs. This prevents MSI-X vector
> > + exhaustion and forces isolated CPUs to share
> > + submission queues.
> > +
> > + Note: Offlining housekeeping CPUs which serve
> > + isolated CPUs will fail. The isolated CPUs must
> > + be offlined before offlining the housekeeping
> > + CPUs.
> > +
> > + Note: When I/O is submitted by an application on
> > + an isolated CPU, the hardware completion
> > + interrupt is handled entirely by a housekeeping
> > + CPU.
>
> This is named io_queue but it does affect I/O in general unless the
> driver uses managed_irqs. This may or may not be clear to the user.
> So the io_queue might not be the perfect name given that affects alles
> devices in the system. We do have just I/O devices using it right now.
>
> I think this still deserves an explanation in
> Documentation/core-api/irq/managed_irq.rst like how to use it, what is
> the expected outcome and how does it interact with the managed_irq
> argument. Does it make sense to use both, is it exclusive or, what would
> be the use case for both arguments.
Regarding the name io_queue, you are correct that it specifically affects
devices employing managed IRQs (i.e., NVMe, SCSI, and blk-mq devices).
The name was chosen because its primary operational objective is to shield
real-time and latency-sensitive isolated cores from multiqueue storage and
block I/O completion interrupts. Non-managed IRQ devices continue to be
governed by standard irqaffinity settings and irqbalance.
I would be happy to provide clear usage guidelines based on the above, if
we can agree on the new proposal, irq_managed:strict?
Kind regards,
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 8/8] docs: add io_queue flag to isolcpus
2026-08-05 16:22 ` Aaron Tomlin
@ 2026-08-21 15:16 ` Sebastian Andrzej Siewior
0 siblings, 0 replies; 24+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-08-21 15:16 UTC (permalink / raw)
To: Aaron Tomlin, frederic, hch, wagi
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, longman, chenridong, hare,
kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
On 2026-08-05 12:22:59 [-0400], Aaron Tomlin wrote:
> Hi Sebastian,
Hi Aaron,
> Yes. Though the underlying mechanisms differ in a fundamental way between
> the two flags:
>
> isolcpus=managed_irq (post-allocation, best-effort):
>
> managed_irq operates downstream at the IRQ affinity level (i.e.,
> kernel/irq/manage.c and kernel/irq/cpuhotplug.c). It attempts to steer
> the effective affinity of already-allocated IRQ vectors away from
> isolated CPUs. However, when a multiqueue storage or networking driver
> allocates one hardware queue per CPU, the affinity mask for an isolated
> CPU's queue contains only that specific CPU. Because the intersection
> between the queue's mask and the housekeeping CPUs is empty,
> managed_irq falls back to assigning the interrupt to the isolated CPU.
> It is therefore inherently "best effort" and cannot guarantee isolation
> for 1-queue-per-CPU devices.
>
>
> isolcpus=io_queue (pre-allocation, strict constraint):
>
> io_queue operates upstream during device probe, MSI-X vector
> calculation, and block-multiqueue topology setup
> (irq_calc_affinity_vectors(), irq_create_affinity_masks(), and blk-mq).
> Rather than attempting to steer vectors after allocation, it caps the
> total number of hardware queues and MSI-X vectors to match the weight
> of the online housekeeping CPUs. Isolated CPUs are strictly excluded
> during initial vector mask generation (group_mask_cpus_evenly()). I/O
> requests submitted from isolated CPUs are routed through shared
> submission queues mapped onto housekeeping cores, ensuring completion
> interrupts land exclusively on housekeeping CPUs.
>
> In summary, while managed_irq influences where already-created interrupts
> land, io_queue restricts how many queues are created and how the hardware
> topology is constructed.
>
> I hope this helps.
Is there a difference if this happens before or after allocation? I
*think* if it is made post-allocation then the driver expects a certain
amount of interrupts which need to be there. But otherwise…
There is no way to limit the amount of queues as far as I am aware which
makes the isolcpus=managed_irq useless as long as there are more queues
than CPUs in the system.
Is there a benefit of having 4 queues which are handled by 2 CPUs or
would it make more sense to use only 2 queues and not "overcommit"?
The problem I am having is to figure out where the managed_irq makes
sense since you need less queues than CPUs and this is hardware
dependent. Say you replace your NVME after the old one broke and boom,
now are all CPUs utilised.
So if managed_irqs would also act pre-allocation then the only
difference would be "best effort" vs "mandatory".
There might be the details around what happens if the CPU goes offline
and can the CPU go offline. I think the block layers drains the I/O
queues and the actual driver does nothing. In the CPUs > queues case the
queues (or a few) are mapped to more than one CPU so if one of the CPUs
goes offline, that IRQ is simply moved to another CPU within its mask
(which could go to the initially isolated CPU if my memory serves me
well).
I am not aware that networking is using this. Judging by
pci_alloc_irq_vectors_affinity() this is mostly scsi and there is one
networking driver (which makes a bit curious how CPU hotplug is
handled). Anyway, there is some effort on the networking side to
consolidate this:
https://lore.kernel.org/20260819-flo-net-7-2-make-stmmac-default-affinity-aware-v1-0-3f79a99cadaf@siemens.com
> > If so, can this be integrated?
>
> I do not want managed_irq unconditionally enforced vector capping. Instead
> of creating a standalone HK_TYPE_IO_QUEUE housekeeping flag, the strict
> vector capping and mask restriction could be integrated under an opt-in
> flag?
I'm asking for breaking the current option because it makes no sense and
so far nobody responded by saying yes, or no that is stupid.
> How about an opt-in flag:
>
> - isolcpus=managed_irq
> Keeps best-effort post-allocation IRQ steering without capping
> hardware queues
>
> - isolcpus=managed_irq_strict (or managed_irq:strict)
> Enables strict pre-allocation queue capping (i.e.,
> irq_calc_affinity_vectors() and blk_mq queue limits)
>
> If the preference is to avoid adding a new top-level isolcpus= flag, I am
> more than happy to refactor io_queue into a strict sub-parameter under
> managed_irq (e.g., isolcpus=managed_irq:strict). This probably makes more
> sense.
Not sure what Frederick's thinks here but I would aim for
managed_irq_strict if we can't change the current behaviour.
It should be also documented if both can be used (or are invalid) and
what to expect if they are mixed.
…
> > This is named io_queue but it does affect I/O in general unless the
> > driver uses managed_irqs. This may or may not be clear to the user.
> > So the io_queue might not be the perfect name given that affects alles
> > devices in the system. We do have just I/O devices using it right now.
> >
> > I think this still deserves an explanation in
> > Documentation/core-api/irq/managed_irq.rst like how to use it, what is
> > the expected outcome and how does it interact with the managed_irq
> > argument. Does it make sense to use both, is it exclusive or, what would
> > be the use case for both arguments.
>
> Regarding the name io_queue, you are correct that it specifically affects
> devices employing managed IRQs (i.e., NVMe, SCSI, and blk-mq devices).
> The name was chosen because its primary operational objective is to shield
> real-time and latency-sensitive isolated cores from multiqueue storage and
> block I/O completion interrupts. Non-managed IRQ devices continue to be
> governed by standard irqaffinity settings and irqbalance.
>
> I would be happy to provide clear usage guidelines based on the above, if
> we can agree on the new proposal, irq_managed:strict?
I *think* ':' will be an invalid character and ignored so maybe the '_'
instead.
> Kind regards,
Sebastian
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (7 preceding siblings ...)
2026-05-21 23:29 ` [PATCH v15 8/8] docs: add io_queue flag to isolcpus Aaron Tomlin
@ 2026-05-26 16:05 ` Daniel Wagner
2026-05-26 22:02 ` Aaron Tomlin
2026-06-17 11:01 ` Aaron Tomlin
` (2 subsequent siblings)
11 siblings, 1 reply; 24+ messages in thread
From: Daniel Wagner @ 2026-05-26 16:05 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
Hi Aaron,
On Thu, May 21, 2026 at 07:29:48PM -0400, Aaron Tomlin wrote:
> Please let me know your thoughts.
>
>
> Changes since v14:
You’re moving fast with these updates! It’s great energy, but it’s
actually moving a bit faster than the review process can keep up with.
I’ve heard from some folks in the CC that they waiting for a 'final'
version.
Is this latest version ready for a full, deep-dive review, or are there
still a few 'knacks' you’re looking to iron out first?
Thanks,
Daniel
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-05-26 16:05 ` [PATCH v15 0/8] blk: honor isolcpus configuration Daniel Wagner
@ 2026-05-26 22:02 ` Aaron Tomlin
0 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-05-26 22:02 UTC (permalink / raw)
To: Daniel Wagner
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, bigeasy, yphbchou0911, wagi, frederic,
longman, chenridong, hare, kch, ming.lei, tom.leiming, steve,
sean, chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1154 bytes --]
On Tue, May 26, 2026 at 06:05:54PM +0200, Daniel Wagner wrote:
> > Please let me know your thoughts.
> >
> >
> > Changes since v14:
>
> You’re moving fast with these updates! It’s great energy, but it’s
> actually moving a bit faster than the review process can keep up with.
> I’ve heard from some folks in the CC that they waiting for a 'final'
> version.
>
> Is this latest version ready for a full, deep-dive review, or are there
> still a few 'knacks' you’re looking to iron out first?
Hi Daniel,
Thank you for making me aware of this. I entirely understand—I certainly
wish to avoid causing review fatigue or unnecessary churn for those copied
on this thread.
To address your query: there remain a few minor concerns. However,
considering the rather rapid pace of recent updates, I am more than happy
to pause the process.
Let us allow the current iteration to settle. I shall hold off on
submitting the next version to ensure everyone has ample time to run their
tests, conduct a thorough review, and offer further feedback on the present
state of the patches.
Kind regards,
--
Aaron Tomlin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (8 preceding siblings ...)
2026-05-26 16:05 ` [PATCH v15 0/8] blk: honor isolcpus configuration Daniel Wagner
@ 2026-06-17 11:01 ` Aaron Tomlin
2026-07-10 15:14 ` Sebastian Andrzej Siewior
2026-07-10 15:21 ` Sebastian Andrzej Siewior
2026-08-07 14:20 ` Ionut Nechita (Wind River)
11 siblings, 1 reply; 24+ messages in thread
From: Aaron Tomlin @ 2026-06-17 11:01 UTC (permalink / raw)
To: axboe, kbusch, hch, sagi, mst
Cc: hare, aacraid, James.Bottomley, martin.petersen, liyihang9,
kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
chandrakanth.patil, sathya.prakash, sreekanth.reddy,
suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, kch,
ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
nick.lange, marco.crivellari, rishil1999, linux-block,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2490 bytes --]
On Thu, May 21, 2026 at 07:29:48PM -0400, Aaron Tomlin wrote:
> Hi,
>
> I have decided to drive this series forward on behalf of Daniel Wagner, the
> original author. The series has been rebased on v7.1-rc4-100-g8bc67e4db64a.
>
> This series introduces a new CPU isolation feature, "isolcpus=io_queue",
> designed to protect isolated cores from the disruptive hardware interrupts
> generated by high-performance multi-queue devices.
>
> When enabled, it fundamentally alters how the generic IRQ subsystem and the
> block layer (blk-mq) map hardware queues:
>
> 1. Restricted IRQ Affinity: Managed hardware interrupts are strictly
> confined to online housekeeping CPUs.
>
> 2. Transparent I/O Submission: Applications running on isolated CPUs
> can still seamlessly submit I/O requests; however, the resulting
> hardware completion interrupts are safely routed to a designated
> housekeeping CPU.
>
> 3. Topology-Aware Queue Allocation: The generic CPU-to-hardware-queue
> mapping logic is extended to distribute hardware contexts evenly
> among the available housekeeping CPUs, preventing MSI-X vector
> exhaustion while maintaining optimal cache locality where possible.
>
> To prevent I/O stalls, the block layer is additionally hardened to reject
> hot-plug requests that attempt to offline a housekeeping CPU if it is the
> last remaining CPU actively serving an online isolated core.
Hi everyone,
I am writing to politely follow up and request feedback on the v15
iteration of the 'isolcpus=io_queue' patch series.
As noted in the cover letter, this version introduces a major architectural
simplification compared to the older v12 design. Specifically, the complex
"top-down" mask plumbing and struct irq_affinity modifications have been
completely abandoned.
Instead, this iteration relies on a much cleaner, centralized approach
using direct isolation querying via housekeeping_cpumask(HK_TYPE_IO_QUEUE)
within the genirq/affinity subsystem. This pivot successfully decouples the
core infrastructure changes from driver-specific implementations, which
should significantly reduce the maintenance burden.
I would greatly appreciate it if anyone has the bandwidth to review this
new approach. Please let me know your thoughts or if there are any further
refinements needed.
Thank you for your time and guidance.
Kind regards,
--
Aaron Tomlin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-06-17 11:01 ` Aaron Tomlin
@ 2026-07-10 15:14 ` Sebastian Andrzej Siewior
0 siblings, 0 replies; 24+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-07-10 15:14 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, hare, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, kch, ming.lei, tom.leiming, steve, sean, chjohnst,
neelx, mproche, nick.lange, marco.crivellari, rishil1999,
linux-block, linux-kernel
On 2026-06-17 07:01:24 [-0400], Aaron Tomlin wrote:
> Hi everyone,
Hi,
> I would greatly appreciate it if anyone has the bandwidth to review this
> new approach. Please let me know your thoughts or if there are any further
> refinements needed.
I assume this is the latest. If so I would try to look at this next MON.
> Thank you for your time and guidance.
>
> Kind regards,
Sebastian
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (9 preceding siblings ...)
2026-06-17 11:01 ` Aaron Tomlin
@ 2026-07-10 15:21 ` Sebastian Andrzej Siewior
2026-08-05 19:22 ` Aaron Tomlin
2026-08-07 14:20 ` Ionut Nechita (Wind River)
11 siblings, 1 reply; 24+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-07-10 15:21 UTC (permalink / raw)
To: Aaron Tomlin
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
On 2026-05-21 19:29:48 [-0400], Aaron Tomlin wrote:
> Hi,
Hi,
> I have decided to drive this series forward on behalf of Daniel Wagner, the
> original author. The series has been rebased on v7.1-rc4-100-g8bc67e4db64a.
>
> This series introduces a new CPU isolation feature, "isolcpus=io_queue",
> designed to protect isolated cores from the disruptive hardware interrupts
> generated by high-performance multi-queue devices.
>
> When enabled, it fundamentally alters how the generic IRQ subsystem and the
> block layer (blk-mq) map hardware queues:
>
> 1. Restricted IRQ Affinity: Managed hardware interrupts are strictly
> confined to online housekeeping CPUs.
>
> 2. Transparent I/O Submission: Applications running on isolated CPUs
> can still seamlessly submit I/O requests; however, the resulting
> hardware completion interrupts are safely routed to a designated
> housekeeping CPU.
>
> 3. Topology-Aware Queue Allocation: The generic CPU-to-hardware-queue
> mapping logic is extended to distribute hardware contexts evenly
> among the available housekeeping CPUs, preventing MSI-X vector
> exhaustion while maintaining optimal cache locality where possible.
>
> To prevent I/O stalls, the block layer is additionally hardened to reject
> hot-plug requests that attempt to offline a housekeeping CPU if it is the
> last remaining CPU actively serving an online isolated core.
>
> The complex "top-down" mask plumbing introduced in v12, which modified
> struct irq_affinity and expanded block layer APIs, has been abandoned. It
> is replaced by a centralised approach: direct isolation querying via
> housekeeping_cpumask(HK_TYPE_IO_QUEUE) within the genirq/affinity
> subsystem. This architectural simplification successfully decouples core
> changes from driver-specific implementations.
>
> Please let me know your thoughts.
I think I asked this or wanted to: Why not mage managed_irqs consider
this? Or is there a case where those two options want a different thing?
With managed_irqs you specify a mask but this is may not be respected if
you have more IRQs than you specify. This means the IRQs will still be
routed to isolated CPUs.
This option is intended to avoid any interrupts on isolated CPUs.
Wouldn't it be possible to allow managed_irqs to restrict a device to
two CPUs only and use two queues only instead of the available 64 or do
I miss something fundamental why those two need to be separate?
Sebastian
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-07-10 15:21 ` Sebastian Andrzej Siewior
@ 2026-08-05 19:22 ` Aaron Tomlin
0 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-08-05 19:22 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
chjohnst, neelx, mproche, nick.lange, marco.crivellari,
rishil1999, linux-block, linux-kernel
On Fri, Jul 10, 2026 at 05:21:59PM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-05-21 19:29:48 [-0400], Aaron Tomlin wrote:
> > Hi,
> Hi,
>
> > I have decided to drive this series forward on behalf of Daniel Wagner, the
> > original author. The series has been rebased on v7.1-rc4-100-g8bc67e4db64a.
> >
> > This series introduces a new CPU isolation feature, "isolcpus=io_queue",
> > designed to protect isolated cores from the disruptive hardware interrupts
> > generated by high-performance multi-queue devices.
> >
> > When enabled, it fundamentally alters how the generic IRQ subsystem and the
> > block layer (blk-mq) map hardware queues:
> >
> > 1. Restricted IRQ Affinity: Managed hardware interrupts are strictly
> > confined to online housekeeping CPUs.
> >
> > 2. Transparent I/O Submission: Applications running on isolated CPUs
> > can still seamlessly submit I/O requests; however, the resulting
> > hardware completion interrupts are safely routed to a designated
> > housekeeping CPU.
> >
> > 3. Topology-Aware Queue Allocation: The generic CPU-to-hardware-queue
> > mapping logic is extended to distribute hardware contexts evenly
> > among the available housekeeping CPUs, preventing MSI-X vector
> > exhaustion while maintaining optimal cache locality where possible.
> >
> > To prevent I/O stalls, the block layer is additionally hardened to reject
> > hot-plug requests that attempt to offline a housekeeping CPU if it is the
> > last remaining CPU actively serving an online isolated core.
> >
> > The complex "top-down" mask plumbing introduced in v12, which modified
> > struct irq_affinity and expanded block layer APIs, has been abandoned. It
> > is replaced by a centralised approach: direct isolation querying via
> > housekeeping_cpumask(HK_TYPE_IO_QUEUE) within the genirq/affinity
> > subsystem. This architectural simplification successfully decouples core
> > changes from driver-specific implementations.
> >
> > Please let me know your thoughts.
>
> I think I asked this or wanted to: Why not mage managed_irqs consider
> this? Or is there a case where those two options want a different thing?
> With managed_irqs you specify a mask but this is may not be respected if
> you have more IRQs than you specify. This means the IRQs will still be
> routed to isolated CPUs.
> This option is intended to avoid any interrupts on isolated CPUs.
> Wouldn't it be possible to allow managed_irqs to restrict a device to
> two CPUs only and use two queues only instead of the available 64 or do
> I miss something fundamental why those two need to be separate?
Hi Sebastian,
Please see my response here [1].
[1]: https://lore.kernel.org/lkml/xjcwes5caiwh3eumqfuvankokb7wzzokleqfkfmkh5sgl333sg@nwlgqvj4vdet/
Kind regards,
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-05-21 23:29 [PATCH v15 0/8] blk: honor isolcpus configuration Aaron Tomlin
` (10 preceding siblings ...)
2026-07-10 15:21 ` Sebastian Andrzej Siewior
@ 2026-08-07 14:20 ` Ionut Nechita (Wind River)
2026-08-10 13:22 ` Aaron Tomlin
11 siblings, 1 reply; 24+ messages in thread
From: Ionut Nechita (Wind River) @ 2026-08-07 14:20 UTC (permalink / raw)
To: atomlin
Cc: axboe, kbusch, hch, sagi, bigeasy, wagi, marco.crivellari,
linux-block, linux-kernel
Hi Aaron,
We're tracking this series downstream -- the managed_irq best-effort
gap for blk-mq/NVMe queue mapping is exactly the limitation we hit on
PREEMPT_RT telecom controllers with narrow housekeeping pools (GNR-D
144T, most cores isolated, 24 ice PFs + 2 NVMe).
When the next revision lands (with the naming/integration changes from
Sebastian's and Marco's feedback), we'd be happy to test it on that
hardware and report back with effective_affinity + NVMe queue mapping
data.
Thanks for driving this forward.
Ionut
^ permalink raw reply [flat|nested] 24+ messages in thread* Re: [PATCH v15 0/8] blk: honor isolcpus configuration
2026-08-07 14:20 ` Ionut Nechita (Wind River)
@ 2026-08-10 13:22 ` Aaron Tomlin
0 siblings, 0 replies; 24+ messages in thread
From: Aaron Tomlin @ 2026-08-10 13:22 UTC (permalink / raw)
To: Ionut Nechita (Wind River)
Cc: axboe, kbusch, hch, sagi, bigeasy, wagi, marco.crivellari,
linux-block, linux-kernel
On Fri, Aug 07, 2026 at 05:20:45PM +0300, Ionut Nechita (Wind River) wrote:
> Hi Aaron,
>
> We're tracking this series downstream -- the managed_irq best-effort
> gap for blk-mq/NVMe queue mapping is exactly the limitation we hit on
> PREEMPT_RT telecom controllers with narrow housekeeping pools (GNR-D
> 144T, most cores isolated, 24 ice PFs + 2 NVMe).
>
> When the next revision lands (with the naming/integration changes from
> Sebastian's and Marco's feedback), we'd be happy to test it on that
> hardware and report back with effective_affinity + NVMe queue mapping
> data.
>
> Thanks for driving this forward.
>
> Ionut
Hi Ionut,
Thank you! I would appreciate that.
Kind reards,
--
Aaron Tomlin
^ permalink raw reply [flat|nested] 24+ messages in thread