diff options
author | Anton Blanchard <anton@samba.org> | 2012-06-27 13:13:52 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-16 09:03:21 -0700 |
commit | ee1602ff18545ddf7f19638fb350e4eec2030c0d (patch) | |
tree | 5fb6a4f86e7ef199685a19a996178b5c9d8e7252 | |
parent | 8057f6c444173496806618f2fe173c2f02fb3995 (diff) | |
download | linux-3.10-ee1602ff18545ddf7f19638fb350e4eec2030c0d.tar.gz linux-3.10-ee1602ff18545ddf7f19638fb350e4eec2030c0d.tar.bz2 linux-3.10-ee1602ff18545ddf7f19638fb350e4eec2030c0d.zip |
powerpc: check_and_cede_processor() never cedes
commit 0b17ba7258db83cd02da560884e053b85de371f2 upstream.
Commit f948501b36c6 ("Make hard_irq_disable() actually hard-disable
interrupts") caused check_and_cede_processor to stop working.
->irq_happened will never be zero right after a hard_irq_disable
so the compiler removes the call to cede_processor completely.
The bug was introduced back in the lazy interrupt handling rework
of 3.4 but was hidden until recently because hard_irq_disable did
nothing.
This issue will eventually appear in 3.4 stable since the
hard_irq_disable fix is marked stable, so mark this one for stable
too.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | arch/powerpc/include/asm/hw_irq.h | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/processor_idle.c | 2 |
2 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 102abd6dbc0..6627a3e1b13 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -102,6 +102,11 @@ static inline void hard_irq_disable(void) /* include/linux/interrupt.h needs hard_irq_disable to be a macro */ #define hard_irq_disable hard_irq_disable +static inline bool lazy_irq_pending(void) +{ + return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS); +} + /* * This is called by asynchronous interrupts to conditionally * re-enable hard interrupts when soft-disabled after having diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 41a34bc4a9a..e61483e8e96 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c @@ -106,7 +106,7 @@ static void check_and_cede_processor(void) * we first hard disable then check. */ hard_irq_disable(); - if (get_paca()->irq_happened == 0) + if (!lazy_irq_pending()) cede_processor(); } |