Patchwork [3.5.y.z,extended,stable] Patch "powerpc: Fix missing/delayed calls to irq_work" has been added to staging queue

mail settings
Submitter Luis Henriques
Date June 17, 2013, 2:46 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/251869/
State New
Headers show


Luis Henriques - June 17, 2013, 2:46 p.m.
This is a note to let you know that I have just added a patch titled

    powerpc: Fix missing/delayed calls to irq_work

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 3de97afe43ff2ef1d94b80e14cb2c97004c28b7a Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <>
Date: Sat, 15 Jun 2013 12:13:40 +1000
Subject: [PATCH] powerpc: Fix missing/delayed calls to irq_work

commit 230b3034793247f61e6a0b08c44cf415f6d92981 upstream.

When replaying interrupts (as a result of the interrupt occurring
while soft-disabled), in the case of the decrementer, we are exclusively
testing for a pending timer target. However we also use decrementer
interrupts to trigger the new "irq_work", which in this case would
be missed.

This change the logic to force a replay in both cases of a timer
boundary reached and a decrementer interrupt having actually occurred
while disabled. The former test is still useful to catch cases where
a CPU having been hard-disabled for a long time completely misses the
interrupt due to a decrementer rollover.

Signed-off-by: Benjamin Herrenschmidt <>
Tested-by: Steven Rostedt <>
Signed-off-by: Luis Henriques <>
 arch/powerpc/kernel/irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 1f017bb..86cb68e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -162,7 +162,7 @@  notrace unsigned int __check_irq_replay(void)
 	 * in case we also had a rollover while hard disabled
 	local_paca->irq_happened &= ~PACA_IRQ_DEC;
-	if (decrementer_check_overflow())
+	if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
 		return 0x900;

 	/* Finally check if an external interrupt happened */