On Tue, 3 Nov 2009, Yong Zhang wrote: > > This happens because the &desc->lock is taken with spin_lock_irqsave and > > just a spin_lock.  In the try_one_irq(), this lock really should be a > > spin_lock_irqsave(). > > > > Cc'ed Ingo and Thomas. > > The reason is that try_one_irq() is called both from hardirq context and softirq > context. And by default the timer handler poll_all_shared_irqs() is > called with irq enabled. > Then the two usage will cause inconsistent. > > So I think the following patch is also workable to you. Yes, that's sufficient. > diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c > index 114e704..11affbc 100644 > --- a/kernel/irq/spurious.c > +++ b/kernel/irq/spurious.c > @@ -111,6 +111,7 @@ static void poll_all_shared_irqs(void) > > for_each_irq_desc(i, desc) { > unsigned int status; > + unsigned long flags; > > if (!i) > continue; > @@ -121,7 +122,9 @@ static void poll_all_shared_irqs(void) > if (!(status & IRQ_SPURIOUS_DISABLED)) > continue; > > + local_irq_save(flags); > try_one_irq(i, desc); > + local_irq_restore(flags); You can even use local_irq_en/disable() here. Thanks, tglx