powerpc/irq: Fix another case of lazy IRQ state getting out of sync
So we have another case of paca->irq_happened getting out of sync with the HW irq state. This can happen when a perfmon interrupt occurs while soft disabled, as it will return to a soft disabled but hard enabled context while leaving a stale PACA_IRQ_HARD_DIS flag set. This patch fixes it, and also adds a test for the condition of those flags being out of sync in arch_local_irq_restore() when CONFIG_TRACE_IRQFLAGS is enabled. This helps catching those gremlins faster (and so far I can't seem see any anymore, so that's good news). Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
@@ -229,6 +229,19 @@ notrace void arch_local_irq_restore(unsigned long en)
|
||||
*/
|
||||
if (unlikely(irq_happened != PACA_IRQ_HARD_DIS))
|
||||
__hard_irq_disable();
|
||||
#ifdef CONFIG_TRACE_IRQFLAG
|
||||
else {
|
||||
/*
|
||||
* We should already be hard disabled here. We had bugs
|
||||
* where that wasn't the case so let's dbl check it and
|
||||
* warn if we are wrong. Only do that when IRQ tracing
|
||||
* is enabled as mfmsr() can be costly.
|
||||
*/
|
||||
if (WARN_ON(mfmsr() & MSR_EE))
|
||||
__hard_irq_disable();
|
||||
}
|
||||
#endif /* CONFIG_TRACE_IRQFLAG */
|
||||
|
||||
set_soft_enabled(0);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user