Bug about sched_4bsd?
Kohji Okuno
okuno.kohji at jp.panasonic.com
Sun Jan 17 05:33:57 UTC 2010
Hello,
I think that sched_4bsd.c:sched_switch() has a problem.
I encounterd the problem that a process could not exit.
That process has multi threads and p_flag was as below.
p_flag : (P_INMEM|P_STOPPED_SINGLE|P_EXEC|P_SINGLE_EXIT|P_PPWAIT|P_CONTROLT)
One thread (THREAD A) was suspended as below.
sched_switch()
mi_switch()
thread_suspend_switch()
thread_single()
exit1()
sys_exit()
td_flags : TDF_NEEDSIGCHK|TDF_ASTPENDING|TDF_CANSWAP|TDF_INMEM
Another thread (THREAD B) was sleeping as below.
sched_switch()
mi_switch()
sleepq_switch()
sleepq_catch_signals()
sleepq_wait_sig()
_cv_wait_sig()
seltdwait()
kern_select()
select()
td_flags : TDF_CANSWAP|TDF_SINTR|TDF_INMEM
That process could not exit, because THREAD B did not execute
"thread_suspend_check()" and THREAD A had been suspended.
I think that the race condition had occurred about td_flags as below.
In sched_switch(), when td->td_lock is not &sched_lock, td->td_lock
will be unlocked as shown below. And then, td->td_flags will change
without td->td_lock.
<<THREAD A>>
kern_thread.c:
int
thread_single(int mode)
{
...
thread_lock(td2);
td2->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
*** I think that td2 specified THREAD B in this time.
<<THREAD B>>
sched_4bsd.c:
void
sched_switch(struct thread *td, struct thread *newtd, int flags)
{
...
/*
* Switch to the sched lock to fix things up and pick
* a new thread.
*/
if (td->td_lock != &sched_lock) {
mtx_lock_spin(&sched_lock);
thread_unlock(td);
}
*** I think that td_lock was sleepqueue_chagin->sc_lock.
...
td->td_lastcpu = td->td_oncpu;
td->td_flags &= ~TDF_NEEDRESCHED;
td->td_owepreempt = 0;
td->td_oncpu = NOCPU;
--
Thanks,
Kohji Okuno.
More information about the freebsd-current
mailing list