Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cab824f6 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Sasha Levin
Browse files

genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP



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: 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


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0b926fdf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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>
+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: