Patchwork [3.5.y.z,extended,stable] Patch "genirq: Avoid deadlock in spurious handling" has been added to staging queue

mail settings
Submitter Luis Henriques
Date Feb. 26, 2013, 4:12 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/223261/
State New
Headers show


Luis Henriques - Feb. 26, 2013, 4:12 p.m.
This is a note to let you know that I have just added a patch titled

    genirq: Avoid deadlock in spurious handling

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 fd467039c01fd1404276dc9c1465898b6169d9c3 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <>
Date: Fri, 23 Nov 2012 10:08:44 +0100
Subject: [PATCH] genirq: Avoid deadlock in spurious handling

commit e716efde75267eab919cdb2bef5b2cb77f305326 upstream.

commit 52553ddf(genirq: fix regression in irqfixup, irqpoll)
introduced a potential deadlock by calling the action handler with the
irq descriptor lock held.

Remove the call and let the handling code run even for an interrupt
where only a single action is registered. That matches the goal of
the above commit and avoids the deadlock.

Document the confusing action = desc->action reload in the handling
loop while at it.

Reported-and-tested-by: "Wang, Warner" <>
Tested-by: Edward Donovan <>
Cc: "Wang, Song-Bo (Stoney)" <>
Signed-off-by: Thomas Gleixner <>
Signed-off-by: Luis Henriques <>
 kernel/irq/spurious.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)



diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 611cd60..7b5f012 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -80,13 +80,11 @@  static int try_one_irq(int irq, struct irq_desc *desc, bool force)

 	 * All handlers must agree on IRQF_SHARED, so we test just the
-	 * first. Check for action->next as well.
+	 * first.
 	action = desc->action;
 	if (!action || !(action->flags & IRQF_SHARED) ||
-	    (action->flags & __IRQF_TIMER) ||
-	    (action->handler(irq, action->dev_id) == IRQ_HANDLED) ||
-	    !action->next)
+	    (action->flags & __IRQF_TIMER))
 		goto out;

 	/* Already running on another processor */
@@ -104,6 +102,7 @@  static int try_one_irq(int irq, struct irq_desc *desc, bool force)
 	do {
 		if (handle_irq_event(desc) == IRQ_HANDLED)
 			ret = IRQ_HANDLED;
+		/* Make sure that there is still a valid action */
 		action = desc->action;
 	} while ((desc->istate & IRQS_PENDING) && action);
 	desc->istate &= ~IRQS_POLL_INPROGRESS;