On Fri, Nov 05, 2010 at 17:52 +0100, Mike Belopuhov wrote:
> or am i trippin' on some high quality drugs? (:
>
although i don't stand corrected, there's another possible window
that would explain this thing:
> ddb{1}> tr
> Debugger(d4320000,d082b116,1,202,1) at Debugger+0x4
> i386_ipi_handler(c0,58,10,10,10) at i386_ipi_handler+0x5f
> Xintripi() at Xintripi+0x47
> --- interrupt ---
> __mp_lock(d0a1d10c,7fffffff,da4154f0,d0a184a0,e08bbf5c) at __mp_lock+0x52
> __mp_acquire_count(d0a1d10c,1,10,d4320000,d4320034,e08bbf8c,0,2,1,0,2f6d)
> at __
> mp_acquire_count+0x20
> mi_switch(d0a1d10c,d4320000,da4154f0,e08bbf90,d03d3a53) at mi_switch+0x168
> sched_idle(d4320000) at sched_idle+0x1cc
> Bad frame pointer: 0xd0b8ae48
> ddb{1}>
this code in the very end of the mi_switch acquires a sched lock after
a kernel_lock, but sched_idle is special and it doesn't have a P_BIGLOCK.
so we'll get a sched_lock and introduce a window for a race untill we
exit mi_switch and caller won't do a SCHED_UNLOCK.
#ifdef MULTIPROCESSOR
/*
* Reacquire the kernel_lock now. We do this after we've
* released the scheduler lock to avoid deadlock, and before
* we reacquire the interlock and the scheduler lock.
*/
if (p->p_flag & P_BIGLOCK)
__mp_acquire_count(&kernel_lock, hold_count);
__mp_acquire_count(&sched_lock, sched_count + 1);
#endif
a possible fix remains the same.