Index: head/sys/kern/kern_exit.c =================================================================== --- head/sys/kern/kern_exit.c +++ head/sys/kern/kern_exit.c @@ -285,6 +285,15 @@ wakeup(&p->p_stype); /* + * If P_PPWAIT is set our parent holds us with p_lock and may + * be waiting on p_pwait. + */ + if (p->p_flag & P_PPWAIT) { + p->p_flag &= ~P_PPWAIT; + cv_broadcast(&p->p_pwait); + } + + /* * Wait for any processes that have a hold on our vmspace to * release their reference. */ @@ -329,13 +338,9 @@ */ EVENTHANDLER_DIRECT_INVOKE(process_exit, p); - /* - * If parent is waiting for us to exit or exec, - * P_PPWAIT is set; we will wakeup the parent below. - */ PROC_LOCK(p); stopprofclock(p); - p->p_flag &= ~(P_TRACED | P_PPWAIT | P_PPTRACE); + p->p_flag &= ~(P_TRACED | P_PPTRACE); p->p_ptevents = 0; /* @@ -636,7 +641,6 @@ * 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; Index: head/sys/kern/kern_fork.c =================================================================== --- head/sys/kern/kern_fork.c +++ head/sys/kern/kern_fork.c @@ -725,6 +725,7 @@ */ _PHOLD(p2); if (fr->fr_flags & RFPPWAIT) { + _PHOLD(p2); td->td_pflags |= TDP_RFPPWAIT; td->td_rfppwait_p = p2; td->td_dbgflags |= TDB_VFORK; Index: head/sys/kern/subr_syscall.c =================================================================== --- head/sys/kern/subr_syscall.c +++ head/sys/kern/subr_syscall.c @@ -257,6 +257,7 @@ } cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz); } + _PRELE(p2); PROC_UNLOCK(p2); if (td->td_dbgflags & TDB_VFORK) {