Skip to content
  • Russ Anderson's avatar
    __do_IRQ does not check IRQ_DISABLED when IRQ_PER_CPU is set · c642b839
    Russ Anderson authored
    
    
    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: default avatarRuss Anderson <rja@sgi.com>
    Cc: "Luck, Tony" <tony.luck@intel.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    c642b839