]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP
authorThomas Gleixner <tglx@linutronix.de>
Thu, 29 Jul 2021 21:51:48 +0000 (23:51 +0200)
committerSasha Levin <sashal@kernel.org>
Thu, 26 Aug 2021 12:36:40 +0000 (08:36 -0400)
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: 18404756765c ("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 a042faefb9b7305c2511f2df0d829ce076096c3c..9504267414a452f6a542c115cdb7ae2a23d720f4 100644 (file)
@@ -535,6 +535,7 @@ struct irq_chip {
  * IRQCHIP_ONESHOT_SAFE:       One shot does not require mask/unmask
  * IRQCHIP_EOI_THREADED:       Chip requires eoi() on unmask in threaded mode
  * IRQCHIP_SUPPORTS_LEVEL_MSI  Chip can provide two doorbells for Level MSIs
+ * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
  */
 enum {
        IRQCHIP_SET_TYPE_MASKED         = (1 <<  0),
@@ -545,6 +546,7 @@ enum {
        IRQCHIP_ONESHOT_SAFE            = (1 <<  5),
        IRQCHIP_EOI_THREADED            = (1 <<  6),
        IRQCHIP_SUPPORTS_LEVEL_MSI      = (1 <<  7),
+       IRQCHIP_AFFINITY_PRE_STARTUP    = (1 << 10),
 };
 
 #include <linux/irqdesc.h>
index 09d914e486a2d32d84b0e002560b834da64427fa..9afbd89b6096ed4cdf7797d27ebb0b1cfab2a2ce 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);