On Wed, 6 Jun 2012, Thomas Gleixner wrote: > On Wed, 6 Jun 2012, Chen Gong wrote: > > 于 2012/6/6 18:23, Thomas Gleixner 写道: > > I think you mean > > > > - del_timer_sync(t); > > smp_call_function_single(cpu, mce_disable_cpu, &action, 1); > > + del_timer_sync(t); > > break; > > No I meant it the way I wrote, but as you don't execute hotplug it's > irrelevant. > > So the obvious candidate is the mce-injection code, which was > obviously never tested with DEBUG_PREEMPT enabled. > > raise_local() can be called with preemption enabled from > raise_mce(). Fix for that below. > > Though I can't see how that would do anything with the timer. I think I found it. Do you have CONFIG_NO_HZ enabled? Then mod_timer() will try to move the timer to a different cpu, when the cpu which is running that code is idle. Bloody obvious :( I'll send out a combo patch with all changes so far later. Thanks, tglx Index: linux-2.6/arch/x86/kernel/cpu/mcheck/mce.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/cpu/mcheck/mce.c +++ linux-2.6/arch/x86/kernel/cpu/mcheck/mce.c @@ -1307,7 +1307,7 @@ void mce_timer_kick(unsigned long interv if (timer_pending(t)) { if (time_before(when, t->expires)) - mod_timer(t, when); + mod_timer_pinned(t, when); } else { t->expires = round_jiffies(when); add_timer_on(t, smp_processor_id());