]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
genirq: Let irq thread follow the effective hard irq affinity
authorThomas Gleixner <tglx@linutronix.de>
Fri, 16 Feb 2018 14:21:20 +0000 (15:21 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 16 Feb 2018 14:28:50 +0000 (15:28 +0100)
In case of threaded interrupts the thread follows the affinity setting of
the hard interrupt. The related function uses the affinity mask which was
set by either from user space or via one of the kernel mechanisms. This
mask can be wider than the resulting effective affinity of the hard
interrupt. As a consequence the thread might become affine to a completely
different CPU.

Use the effective interrupt affinity if the architecture supports it, so
the hard interrupt and the thread stay on the same CPU.

Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
kernel/irq/manage.c

index 0f922729bab9b202d1d79054dee2ff56d8a523a2..d2b3c59f12009fbae1ad9f7ffd03f94822a8a6f7 100644 (file)
@@ -855,10 +855,14 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
         * This code is triggered unconditionally. Check the affinity
         * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
         */
-       if (cpumask_available(desc->irq_common_data.affinity))
-               cpumask_copy(mask, desc->irq_common_data.affinity);
-       else
+       if (cpumask_available(desc->irq_common_data.affinity)) {
+               const struct cpumask *m;
+
+               m = irq_data_get_effective_affinity_mask(&desc->irq_data);
+               cpumask_copy(mask, m);
+       } else {
                valid = false;
+       }
        raw_spin_unlock_irq(&desc->lock);
 
        if (valid)