]> git.baikalelectronics.ru Git - kernel.git/commitdiff
genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP
authorThomas Gleixner <tglx@linutronix.de>
Thu, 29 Jul 2021 21:51:48 +0000 (23:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Aug 2021 06:57:02 +0000 (08:57 +0200)
commit 826da771291fc25a428e871f9e7fb465e390f852 upstream.

X86 IO/APIC and MSI interrupts (when used without interrupts remapping)
require that the affinity setup on startup is done before the interrupt is
enabled for the first time as the non-remapped operation mode cannot safely
migrate enabled interrupts from arbitrary contexts. Provide a new irq chip
flag which allows affected hardware to request this.

This has to be opt-in because there have been reports in the past that some
interrupt chips cannot handle affinity setting before startup.

Fixes: fdd62585f1cd ("genirq: Expose default irq affinity mask (take 3)")
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210729222542.779791738@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/irq.h
kernel/irq/chip.c

index e9e69c511ea9236f683b1a8ef1ed8197e98735c2..5655da9eb1fb9377382f2d02e7f74051202d2566 100644 (file)
@@ -542,6 +542,7 @@ struct irq_chip {
  * IRQCHIP_EOI_THREADED:       Chip requires eoi() on unmask in threaded mode
  * IRQCHIP_SUPPORTS_LEVEL_MSI  Chip can provide two doorbells for Level MSIs
  * IRQCHIP_SUPPORTS_NMI:       Chip can deliver NMIs, only for root irqchips
+ * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
  */
 enum {
        IRQCHIP_SET_TYPE_MASKED         = (1 <<  0),
@@ -553,6 +554,7 @@ enum {
        IRQCHIP_EOI_THREADED            = (1 <<  6),
        IRQCHIP_SUPPORTS_LEVEL_MSI      = (1 <<  7),
        IRQCHIP_SUPPORTS_NMI            = (1 <<  8),
+       IRQCHIP_AFFINITY_PRE_STARTUP    = (1 << 10),
 };
 
 #include <linux/irqdesc.h>
index b76703b2c0af28582e29252b5901578d9aeed532..856f0297dc7382d368b0c141774dc1394dcef5ef 100644 (file)
@@ -265,8 +265,11 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
        } else {
                switch (__irq_startup_managed(desc, aff, force)) {
                case IRQ_STARTUP_NORMAL:
+                       if (d->chip->flags & IRQCHIP_AFFINITY_PRE_STARTUP)
+                               irq_setup_affinity(desc);
                        ret = __irq_startup(desc);
-                       irq_setup_affinity(desc);
+                       if (!(d->chip->flags & IRQCHIP_AFFINITY_PRE_STARTUP))
+                               irq_setup_affinity(desc);
                        break;
                case IRQ_STARTUP_MANAGED:
                        irq_do_set_affinity(d, aff, false);