[PATCH RFC 2/3] genirq: Honor existing IRQ affinities when setting affinity hints

Florian Bezdeka florian.bezdeka at siemens.com
Wed Aug 19 07:30:31 PDT 2026


Some device drivers implement an IRQ balancing / spreading mechanism
based on cpumask_local_spread() and irq_set_affinity_hint() (deprecated)
or irq_set_affinity_and_hint().

__irq_apply_affinity_hint() was overwriting already configured
affinities and with that violating user defined affinities.

This was especially a problem on systems with isolated CPUs, a common
pattern on PREEMPT_RT enabled systems. Device IRQs were balanced over
CPUs that were isolated for RT workloads.

Note that only the first call of irq_set_affinity_hint() and
irq_set_affinity_and_hint() - for each IRQ - will have any effect.
Afterward affinities might be controlled from userspace using the
/proc/irq/<n>/smp_affinity{_list} interface.

Signed-off-by: Florian Bezdeka <florian.bezdeka at siemens.com>
---
 kernel/irq/manage.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7eb07e3bdb4c2419e0a58a75c29d88b4b00b8287..3937ba24df6d63375dda88164cf92fd49e70a3eb 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -503,11 +503,21 @@ EXPORT_SYMBOL_GPL(irq_force_affinity);
 
 int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m, bool setaffinity)
 {
+	struct irq_data *irq_data;
 	int ret = -EINVAL;
 
 	scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
 		scoped_irqdesc->affinity_hint = m;
+		irq_data = irq_desc_get_irq_data(scoped_irqdesc);
 		ret = 0;
+
+		/*
+		 * Do not overwrite the affinity in case an affinity for this
+		 * IRQ has already been requested, e.g. by writing to
+		 * /proc/irq/<n>/smp_affinity
+		 */
+		if (irqd_affinity_was_set(irq_data))
+			setaffinity = false;
 	}
 
 	if (!ret && m && setaffinity)

-- 
2.55.0




More information about the linux-arm-kernel mailing list