powerpc/64: Don't recurse irq replay
authorNicholas Piggin <npiggin@gmail.com>
Sat, 21 Jan 2023 10:26:18 +0000 (20:26 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Mar 2023 07:50:30 +0000 (08:50 +0100)
commitac872bb004c3033afef0bfe06d3558744aeca739
treedf3c5cdb266aa7385c4da39eca1e276f555c7955
parent5759afd5e5844cfe1483273db0e1b590a73eeec0
powerpc/64: Don't recurse irq replay

[ Upstream commit 5746ca131e2496ccd5bb4d7a0244d6c38070cbf5 ]

Interrupt handlers called by soft-pending irq replay code can run
softirqs, softirq replay enables and disables local irqs, which allows
interrupts to come in including soft-masked interrupts, and it can
cause pending irqs to be replayed again. That makes the soft irq replay
state machine and possible races more complicated and fragile than it
needs to be.

Use irq_enter/irq_exit around irq replay to prevent softirqs running
while interrupts are being replayed. Softirqs will now be run at the
irq_exit() call after all the irq replaying is done. This prevents irqs
being replayed while irqs are being replayed, and should hopefully make
things simpler and easier to think about and debug.

A new PACA_IRQ_REPLAYING is added to prevent asynchronous interrupt
handlers hard-enabling EE while pending irqs are being replayed, because
that causes new pending irqs to arrive which is also a complexity. This
means pending irqs won't be profiled quite so well because perf irqs
can't be taken.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20230121102618.2824429-1-npiggin@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/include/asm/hw_irq.h
arch/powerpc/kernel/irq_64.c