From: Aaron Tomlin <atomlin@atomlin.com>
To: axboe@kernel.dk, tglx@kernel.org, aacraid@microsemi.com,
James.Bottomley@HansenPartnership.com, mkp@kernel.org,
frederic@kernel.org, bigeasy@linutronix.de
Cc: atomlin@atomlin.com, ionut.nechita@windriver.com, corbet@lwn.net,
vincent.guittot@linaro.org, mingo@redhat.com,
peterz@infradead.org, radu@rendec.net, akpm@linux-foundation.org,
steve@abita.co, sean@ashe.io, chjohnst@gmail.com, neelx@suse.com,
mproche@gmail.com, nick.lange@gmail.com,
marco.crivellari@suse.com, rishil1999@outlook.com,
linux-doc@vger.kernel.org, linux-block@vger.kernel.org,
linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v16 8/9] genirq/affinity: Restrict managed IRQ affinity to housekeeping CPUs
Date: Thu, 10 Sep 2026 12:42:36 -0400 [thread overview]
Message-ID: <20260910164237.500196-9-atomlin@atomlin.com> (raw)
In-Reply-To: <20260910164237.500196-1-atomlin@atomlin.com>
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=managed_irq_strict"), 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_MANAGED_IRQ_STRICT 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 multi-set scaling
Updated irq_calc_affinity_vectors() to bound the maximum number
of allocated vectors to the weight of the housekeeping mask for
single-set drivers. For drivers providing a calc_sets()
callback, vector calculations continue to scale with the
driver's requested set sizes (maxvec - resv), preventing
unnecessary queue contention across distinct functional sets
while irq_create_affinity_masks() guarantees that all allocated
vectors remain strictly restricted to housekeeping 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 | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c
index 78f2418a8925..7796882a567a 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_MANAGED_IRQ_STRICT);
+ bool hk_enabled = housekeeping_enabled(HK_TYPE_MANAGED_IRQ_STRICT);
/*
* 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 */
@@ -117,8 +130,10 @@ unsigned int irq_calc_affinity_vectors(unsigned int minvec, unsigned int maxvec,
if (affd->calc_sets)
set_vecs = maxvec - resv;
+ else if (housekeeping_enabled(HK_TYPE_MANAGED_IRQ_STRICT))
+ set_vecs = cpumask_weight(housekeeping_cpumask(HK_TYPE_MANAGED_IRQ_STRICT));
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.55.0
next prev parent reply other threads:[~2026-09-10 16:43 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 16:42 [PATCH v16 0/9] blk: honor isolcpus configuration Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 1/9] scsi: aacraid: use block layer helpers to calculate num of queues Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 2/9] lib/group_cpus: remove dead !SMP code Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 3/9] lib/group_cpus: Add group_mask_cpus_evenly() Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 4/9] sched/isolation: Prevent out-of-bounds read in isolcpus= boot parameter parser Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 5/9] isolation: Introduce managed_irq_strict isolcpus type Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 6/9] blk-mq: use hk cpus only when isolcpus=managed_irq_strict is enabled Aaron Tomlin
2026-09-10 16:42 ` [PATCH v16 7/9] blk-mq: prevent offlining hk CPUs with associated online isolated CPUs Aaron Tomlin
2026-09-10 16:42 ` Aaron Tomlin [this message]
2026-09-10 16:42 ` [PATCH v16 9/9] docs: add managed_irq_strict flag to isolcpus Aaron Tomlin
2026-09-10 18:26 ` [PATCH v16 0/9] blk: honor isolcpus configuration Aaron Tomlin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260910164237.500196-9-atomlin@atomlin.com \
--to=atomlin@atomlin.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=aacraid@microsemi.com \
--cc=akpm@linux-foundation.org \
--cc=axboe@kernel.dk \
--cc=bigeasy@linutronix.de \
--cc=chjohnst@gmail.com \
--cc=corbet@lwn.net \
--cc=frederic@kernel.org \
--cc=ionut.nechita@windriver.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=marco.crivellari@suse.com \
--cc=mingo@redhat.com \
--cc=mkp@kernel.org \
--cc=mproche@gmail.com \
--cc=neelx@suse.com \
--cc=nick.lange@gmail.com \
--cc=peterz@infradead.org \
--cc=radu@rendec.net \
--cc=rishil1999@outlook.com \
--cc=sean@ashe.io \
--cc=steve@abita.co \
--cc=tglx@kernel.org \
--cc=vincent.guittot@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®