1
0
Fork 0

irqchip/gic-v3: Remove acknowledge loop

Multiple interrupts pending for a CPU is actually rare. Doing an
acknowledge loop does not give much better performance or even can
deteriorate them.

Do not loop when an interrupt has been acknowledged, just return
from interrupt and wait for another one to be raised.

Tested-by: Daniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: Julien Thierry <julien.thierry@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
Julien Thierry 2018-08-28 16:51:29 +01:00 committed by Marc Zyngier
parent 079f453200
commit 342677d70a

View file

@ -348,48 +348,45 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
{ {
u32 irqnr; u32 irqnr;
do { irqnr = gic_read_iar();
irqnr = gic_read_iar();
if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) { if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
int err; int err;
if (static_branch_likely(&supports_deactivate_key)) if (static_branch_likely(&supports_deactivate_key))
gic_write_eoir(irqnr);
else
isb();
err = handle_domain_irq(gic_data.domain, irqnr, regs);
if (err) {
WARN_ONCE(true, "Unexpected interrupt received!\n");
if (static_branch_likely(&supports_deactivate_key)) {
if (irqnr < 8192)
gic_write_dir(irqnr);
} else {
gic_write_eoir(irqnr);
}
}
continue;
}
if (irqnr < 16) {
gic_write_eoir(irqnr); gic_write_eoir(irqnr);
if (static_branch_likely(&supports_deactivate_key)) else
gic_write_dir(irqnr); isb();
#ifdef CONFIG_SMP
/* err = handle_domain_irq(gic_data.domain, irqnr, regs);
* Unlike GICv2, we don't need an smp_rmb() here. if (err) {
* The control dependency from gic_read_iar to WARN_ONCE(true, "Unexpected interrupt received!\n");
* the ISB in gic_write_eoir is enough to ensure if (static_branch_likely(&supports_deactivate_key)) {
* that any shared data read by handle_IPI will if (irqnr < 8192)
* be read after the ACK. gic_write_dir(irqnr);
*/ } else {
handle_IPI(irqnr, regs); gic_write_eoir(irqnr);
#else }
WARN_ONCE(true, "Unexpected SGI received!\n");
#endif
continue;
} }
} while (irqnr != ICC_IAR1_EL1_SPURIOUS); return;
}
if (irqnr < 16) {
gic_write_eoir(irqnr);
if (static_branch_likely(&supports_deactivate_key))
gic_write_dir(irqnr);
#ifdef CONFIG_SMP
/*
* Unlike GICv2, we don't need an smp_rmb() here.
* The control dependency from gic_read_iar to
* the ISB in gic_write_eoir is enough to ensure
* that any shared data read by handle_IPI will
* be read after the ACK.
*/
handle_IPI(irqnr, regs);
#else
WARN_ONCE(true, "Unexpected SGI received!\n");
#endif
}
} }
static void __init gic_dist_init(void) static void __init gic_dist_init(void)