Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c642b8391cf8efc3622cc97329a0f46e7cbb70b8
Commit:     c642b8391cf8efc3622cc97329a0f46e7cbb70b8
Parent:     57d5f66b86079efac5c9a7843cce2a9bcbe58fb8
Author:     Russ Anderson <[EMAIL PROTECTED]>
AuthorDate: Wed Nov 14 17:00:15 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Nov 14 18:45:43 2007 -0800

    __do_IRQ does not check IRQ_DISABLED when IRQ_PER_CPU is set
    
    In __do_IRQ(), the normal case is that IRQ_DISABLED is checked and if set
    the handler (handle_IRQ_event()) is not called.
    
    Earlier in __do_IRQ(), if IRQ_PER_CPU is set the code does not check
    IRQ_DISABLED and calls the handler even though IRQ_DISABLED is set.  This
    behavior seems unintentional.
    
    One user encountering this behavior is the CPE handler (in
    arch/ia64/kernel/mca.c).  When the CPE handler encounters too many CPEs
    (such as a solid single bit error), it sets up a polling timer and disables
    the CPE interrupt (to avoid excessive overhead logging the stream of single
    bit errors).  disable_irq_nosync() is called which sets IRQ_DISABLED.  The
    IRQ_PER_CPU flag was previously set (in ia64_mca_late_init()).  The net
    result is the CPE handler gets called even though it is marked disabled.
    
    If the behavior of not checking IRQ_DISABLED when IRQ_PER_CPU is set is
    intentional, it would be worthy of a comment describing the intended
    behavior.  disable_irq_nosync() does call chip->disable() to provide a
    chipset specifiec interface for disabling the interrupt, which avoids this
    issue when used.
    
    Signed-off-by: Russ Anderson <[EMAIL PROTECTED]>
    Cc: "Luck, Tony" <[EMAIL PROTECTED]>
    Cc: Thomas Gleixner <[EMAIL PROTECTED]>
    Cc: Ingo Molnar <[EMAIL PROTECTED]>
    Cc: Bjorn Helgaas <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 kernel/irq/handle.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index e391cbb..dc335ad 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -178,9 +178,11 @@ fastcall unsigned int __do_IRQ(unsigned int irq)
                 */
                if (desc->chip->ack)
                        desc->chip->ack(irq);
-               action_ret = handle_IRQ_event(irq, desc->action);
-               if (!noirqdebug)
-                       note_interrupt(irq, desc, action_ret);
+               if (likely(!(desc->status & IRQ_DISABLED))) {
+                       action_ret = handle_IRQ_event(irq, desc->action);
+                       if (!noirqdebug)
+                               note_interrupt(irq, desc, action_ret);
+               }
                desc->chip->end(irq);
                return 1;
        }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to