Date: Sun, 17 Jan 2010 15:28:35 +0900 (JST) From: Kohji Okuno <okuno.kohji@jp.panasonic.com> To: freebsd-current@freebsd.org Cc: okuno.kohji@jp.panasonic.com Subject: Re: Bug about sched_4bsd? Message-ID: <20100117.152835.119882392487126976.okuno.kohji@jp.panasonic.com> In-Reply-To: <20100117.142200.321689433999177718.okuno.kohji@jp.panasonic.com> References: <20100117.142200.321689433999177718.okuno.kohji@jp.panasonic.com>
next in thread | previous in thread | raw e-mail | index | archive | help
----Next_Part(Sun_Jan_17_15_28_35_2010_654)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hello,
Could you check sched_4bsd.patch, please?
--
Best regards,
Kohji Okuno.
> 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.
>
> _______________________________________________
> freebsd-current@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"
----Next_Part(Sun_Jan_17_15_28_35_2010_654)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="sched_4bsd.patch"
diff --git a/kern/sched_4bsd.c b/kern/sched_4bsd.c
index 2a8c442..5602493 100644
--- a/kern/sched_4bsd.c
+++ b/kern/sched_4bsd.c
@@ -269,8 +269,18 @@ maybe_resched(struct thread *td)
{
THREAD_LOCK_ASSERT(td, MA_OWNED);
+#if 1 /* Added */
+ if (td->td_lock != &sched_lock) {
+ mtx_lock_spin(&sched_lock);
+ }
+#endif
if (td->td_priority < curthread->td_priority)
curthread->td_flags |= TDF_NEEDRESCHED;
+#if 1 /* Added */
+ if (td->td_lock != &sched_lock) {
+ mtx_unlock_spin(&sched_lock);
+ }
+#endif
}
/*
@@ -928,6 +938,12 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
THREAD_LOCK_ASSERT(td, MA_OWNED);
+#if 1 /* Moved */
+ td->td_lastcpu = td->td_oncpu;
+ td->td_flags &= ~TDF_NEEDRESCHED;
+ td->td_owepreempt = 0;
+ td->td_oncpu = NOCPU;
+#endif
/*
* Switch to the sched lock to fix things up and pick
* a new thread.
@@ -943,10 +959,12 @@ sched_switch(struct thread *td, struct thread *newtd, int flags)
if (newtd)
newtd->td_flags |= (td->td_flags & TDF_NEEDRESCHED);
+#if 0 /* Original */
td->td_lastcpu = td->td_oncpu;
td->td_flags &= ~TDF_NEEDRESCHED;
td->td_owepreempt = 0;
td->td_oncpu = NOCPU;
+#endif
/*
* At the last moment, if this thread is still marked RUNNING,
----Next_Part(Sun_Jan_17_15_28_35_2010_654)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100117.152835.119882392487126976.okuno.kohji>
