From ccad2ebfb201232304a87b7e7df40462dbede7b5 Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 5 Dec 2008 20:50:24 +0000 Subject: Several threads in a process may do vfork() simultaneously. Then, all parent threads sleep on the parent' struct proc until corresponding child releases the vmspace. Each sleep is interlocked with proc mutex of the child, that triggers assertion in the sleepq_add(). The assertion requires that at any time, all simultaneous sleepers for the channel use the same interlock. Silent the assertion by using conditional variable allocated in the child. Broadcast the variable event on exec() and exit(). Since struct proc * sleep wait channel is overloaded for several unrelated events, I was unable to remove wakeups from the places where cv_broadcast() is added, except exec(). Reported and tested by: ganbold Suggested and reviewed by: jhb MFC after: 2 week --- sys/kern/kern_exit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sys/kern/kern_exit.c') diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 3b45233..4b4a417 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -543,6 +543,7 @@ exit1(struct thread *td, int rv) * proc lock. */ wakeup(p->p_pptr); + cv_broadcast(&p->p_pwait); sched_exit(p->p_pptr, td); PROC_SLOCK(p); p->p_state = PRS_ZOMBIE; @@ -774,6 +775,7 @@ loop: PROC_UNLOCK(p); tdsignal(t, NULL, SIGCHLD, p->p_ksi); wakeup(t); + cv_broadcast(&p->p_pwait); PROC_UNLOCK(t); sx_xunlock(&proctree_lock); return (0); -- cgit v1.1