From owner-svn-src-head@FreeBSD.ORG Fri Dec 5 20:54:42 2008 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 045F21065672 for ; Fri, 5 Dec 2008 20:54:42 +0000 (UTC) (envelope-from julian@elischer.org) Received: from outG.internet-mail-service.net (outg.internet-mail-service.net [216.240.47.230]) by mx1.freebsd.org (Postfix) with ESMTP id DCEC28FC0A for ; Fri, 5 Dec 2008 20:54:41 +0000 (UTC) (envelope-from julian@elischer.org) Received: from idiom.com (mx0.idiom.com [216.240.32.160]) by out.internet-mail-service.net (Postfix) with ESMTP id 124A424E9; Fri, 5 Dec 2008 12:54:42 -0800 (PST) X-Client-Authorized: MaGic Cook1e X-Client-Authorized: MaGic Cook1e X-Client-Authorized: MaGic Cook1e X-Client-Authorized: MaGic Cook1e Received: from julian-mac.elischer.org (home.elischer.org [216.240.48.38]) by idiom.com (Postfix) with ESMTP id 3305A2D601B; Fri, 5 Dec 2008 12:54:42 -0800 (PST) Message-ID: <49399510.2030104@elischer.org> Date: Fri, 05 Dec 2008 12:54:40 -0800 From: Julian Elischer User-Agent: Thunderbird 2.0.0.18 (Macintosh/20081105) MIME-Version: 1.0 To: Konstantin Belousov References: <200812052050.mB5KoOcV072648@svn.freebsd.org> In-Reply-To: <200812052050.mB5KoOcV072648@svn.freebsd.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r185647 - in head/sys: kern sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Dec 2008 20:54:42 -0000 Konstantin Belousov wrote: > Author: kib > Date: Fri Dec 5 20:50:24 2008 > New Revision: 185647 > URL: http://svn.freebsd.org/changeset/base/185647 > > Log: > 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. We DID have a thread_single() in the fork code so that only one thread would proceed through the fork itself at a time. However it was removed last year as it proved to be a problem in some cases. Maybe we need to look at replacing it in some way. > > 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 > > Modified: > head/sys/kern/kern_exec.c > head/sys/kern/kern_exit.c > head/sys/kern/kern_fork.c > head/sys/kern/kern_proc.c > head/sys/sys/proc.h > > Modified: head/sys/kern/kern_exec.c > ============================================================================== > --- head/sys/kern/kern_exec.c Fri Dec 5 20:40:02 2008 (r185646) > +++ head/sys/kern/kern_exec.c Fri Dec 5 20:50:24 2008 (r185647) > @@ -609,7 +609,7 @@ interpret: > p->p_flag |= P_EXEC; > if (p->p_pptr && (p->p_flag & P_PPWAIT)) { > p->p_flag &= ~P_PPWAIT; > - wakeup(p->p_pptr); > + cv_broadcast(&p->p_pwait); > } > > /* > > Modified: head/sys/kern/kern_exit.c > ============================================================================== > --- head/sys/kern/kern_exit.c Fri Dec 5 20:40:02 2008 (r185646) > +++ head/sys/kern/kern_exit.c Fri Dec 5 20:50:24 2008 (r185647) > @@ -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); > > Modified: head/sys/kern/kern_fork.c > ============================================================================== > --- head/sys/kern/kern_fork.c Fri Dec 5 20:40:02 2008 (r185646) > +++ head/sys/kern/kern_fork.c Fri Dec 5 20:50:24 2008 (r185647) > @@ -754,7 +754,7 @@ again: > */ > PROC_LOCK(p2); > while (p2->p_flag & P_PPWAIT) > - msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); > + cv_wait(&p2->p_pwait, &p2->p_mtx); > PROC_UNLOCK(p2); > > /* > > Modified: head/sys/kern/kern_proc.c > ============================================================================== > --- head/sys/kern/kern_proc.c Fri Dec 5 20:40:02 2008 (r185646) > +++ head/sys/kern/kern_proc.c Fri Dec 5 20:50:24 2008 (r185647) > @@ -231,6 +231,7 @@ proc_init(void *mem, int size, int flags > bzero(&p->p_mtx, sizeof(struct mtx)); > mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); > mtx_init(&p->p_slock, "process slock", NULL, MTX_SPIN | MTX_RECURSE); > + cv_init(&p->p_pwait, "ppwait"); > TAILQ_INIT(&p->p_threads); /* all threads in proc */ > EVENTHANDLER_INVOKE(process_init, p); > p->p_stats = pstats_alloc(); > > Modified: head/sys/sys/proc.h > ============================================================================== > --- head/sys/sys/proc.h Fri Dec 5 20:40:02 2008 (r185646) > +++ head/sys/sys/proc.h Fri Dec 5 20:50:24 2008 (r185647) > @@ -40,6 +40,7 @@ > > #include /* For struct callout. */ > #include /* For struct klist. */ > +#include > #ifndef _KERNEL > #include > #endif > @@ -540,6 +541,7 @@ struct proc { > STAILQ_HEAD(, ktr_request) p_ktr; /* (o) KTR event queue. */ > LIST_HEAD(, mqueue_notifier) p_mqnotifier; /* (c) mqueue notifiers.*/ > struct kdtrace_proc *p_dtrace; /* (*) DTrace-specific data. */ > + struct cv p_pwait; /* (*) wait cv for exit/exec */ > }; > > #define p_session p_pgrp->pg_session