Patchwork powerpc: check_and_cede_processor never cedes

login
register
mail settings
Submitter Anton Blanchard
Date June 27, 2012, 10:45 p.m.
Message ID <20120628084509.4caec81d@kryten>
Download mbox | patch
Permalink /patch/167756/
State Superseded
Headers show

Comments

Anton Blanchard - June 27, 2012, 10:45 p.m.
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>  
Cc: stable@vger.kernel.org
---
Benjamin Herrenschmidt - June 27, 2012, 10:51 p.m.
On Thu, 2012-06-28 at 08:45 +1000, Anton Blanchard wrote:
>  	hard_irq_disable();
> -	if (get_paca()->irq_happened == 0)
> +	if (get_paca()->irq_happened == PACA_IRQ_HARD_DIS)
>  		cede_processor();

I'd rather add a helper, something like lazy_irq_pending()
and hide the actual check for the bits in irq_happened, in
case we change the scheme again.

Something like:

static inline bool lazy_irq_pending(void)
{
	return !!(get_paca()->irq_happened & ~PACA_IRQ_HARD_DIS);
}

Cheers,
Ben.

Patch

Index: linux-build/arch/powerpc/platforms/pseries/processor_idle.c
===================================================================
--- linux-build.orig/arch/powerpc/platforms/pseries/processor_idle.c	2012-06-27 21:20:45.403761715 +1000
+++ linux-build/arch/powerpc/platforms/pseries/processor_idle.c	2012-06-27 21:57:14.796788823 +1000
@@ -106,7 +106,7 @@  static void check_and_cede_processor(voi
 	 * we first hard disable then check.
 	 */
 	hard_irq_disable();
-	if (get_paca()->irq_happened == 0)
+	if (get_paca()->irq_happened == PACA_IRQ_HARD_DIS)
 		cede_processor();
 }