*
  * (The other 100-of-100,000 interrupts may have been a correctly
  *  functioning device sharing an IRQ with the failing one)
- *
- * Called under desc->lock
  */
-
 static void
 __report_bad_irq(unsigned int irq, struct irq_desc *desc,
                 irqreturn_t action_ret)
 {
        struct irqaction *action;
+       unsigned long flags;
 
        if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
                printk(KERN_ERR "irq event %d: bogus return value %x\n",
        dump_stack();
        printk(KERN_ERR "handlers:\n");
 
+       /*
+        * We need to take desc->lock here. note_interrupt() is called
+        * w/o desc->lock held, but IRQ_PROGRESS set. We might race
+        * with something else removing an action. It's ok to take
+        * desc->lock here. See synchronize_irq().
+        */
+       raw_spin_lock_irqsave(&desc->lock, flags);
        action = desc->action;
        while (action) {
                printk(KERN_ERR "[<%p>]", action->handler);
                printk("\n");
                action = action->next;
        }
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
 }
 
 static void