Commit 826da771 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP



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: 18404756 ("genirq: Expose default irq affinity mask (take 3)")
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210729222542.779791738@linutronix.de
parent 77e89afc
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -569,6 +569,7 @@ struct irq_chip {
 * IRQCHIP_SUPPORTS_NMI:              Chip can deliver NMIs, only for root irqchips
 * IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND:  Invokes __enable_irq()/__disable_irq() for wake irqs
 *                                    in the suspend path if they are in disabled state
 * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
 */
enum {
	IRQCHIP_SET_TYPE_MASKED			= (1 <<  0),
@@ -581,6 +582,7 @@ enum {
	IRQCHIP_SUPPORTS_LEVEL_MSI		= (1 <<  7),
	IRQCHIP_SUPPORTS_NMI			= (1 <<  8),
	IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND	= (1 <<  9),
	IRQCHIP_AFFINITY_PRE_STARTUP		= (1 << 10),
};

#include <linux/irqdesc.h>
+4 −1
Original line number Diff line number Diff line
@@ -265,7 +265,10 @@ 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);
			if (!(d->chip->flags & IRQCHIP_AFFINITY_PRE_STARTUP))
				irq_setup_affinity(desc);
			break;
		case IRQ_STARTUP_MANAGED: