From owner-p4-projects@FreeBSD.ORG Thu Jul 14 18:10:52 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 80F1216A421; Thu, 14 Jul 2005 18:10:52 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2F80516A41F for ; Thu, 14 Jul 2005 18:10:52 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D7A0E43D45 for ; Thu, 14 Jul 2005 18:10:51 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6EIAp0p000763 for ; Thu, 14 Jul 2005 18:10:51 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6EIApG6000760 for perforce@freebsd.org; Thu, 14 Jul 2005 18:10:51 GMT (envelope-from jhb@freebsd.org) Date: Thu, 14 Jul 2005 18:10:51 GMT Message-Id: <200507141810.j6EIApG6000760@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 80196 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2005 18:10:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=80196 Change 80196 by jhb@jhb_slimer on 2005/07/14 18:09:51 Try to close a race between wait() free'ing the vmspace out from under the last thread that is still trying to exit. Reported by: ps Affected files ... .. //depot/projects/smpng/sys/kern/kern_exit.c#97 edit Differences ... ==== //depot/projects/smpng/sys/kern/kern_exit.c#97 (text+ko) ==== @@ -487,6 +487,9 @@ */ cpu_exit(td); + WITNESS_WARN(WARN_PANIC, &proctree_lock.sx_object, + "process (pid %d) exiting", p->p_pid); + PROC_LOCK(p); PROC_LOCK(p->p_pptr); sx_xunlock(&proctree_lock); @@ -495,20 +498,16 @@ * We have to wait until after acquiring all locks before * changing p_state. We need to avoid all possible context * switches (including ones from blocking on a mutex) while - * marked as a zombie. + * marked as a zombie. We also have to set the zombie state + * before we release the parent process' proc lock to avoid + * a lost wakeup. So, we first call wakeup, then we grab the + * sched lock, update the state, and release the parent process' + * proc lock. */ + wakeup(p->p_pptr); mtx_lock_spin(&sched_lock); p->p_state = PRS_ZOMBIE; - - critical_enter(); - mtx_unlock_spin(&sched_lock); - wakeup(p->p_pptr); - PROC_UNLOCK(p->p_pptr); - WITNESS_WARN(WARN_PANIC, &p->p_mtx.mtx_object, - "process (pid %d) exiting", p->p_pid); - mtx_lock_spin(&sched_lock); - critical_exit(); /* Do the same timestamp bookkeeping that mi_switch() would do. */ binuptime(&new_switchtime); @@ -626,6 +625,20 @@ nfound++; if (p->p_state == PRS_ZOMBIE) { + + /* + * It is possible that the last thread of this + * process is still running on another CPU + * in thread_exit() after having dropped the process + * lock via PROC_UNLOCK() but before it has completed + * cpu_throw(). In that case, the other thread must + * still hold sched_lock, so simply by acquiring + * sched_lock once we will wait long enough for the + * thread to exit in that case. + */ + mtx_lock_spin(&sched_lock); + mtx_unlock_spin(&sched_lock); + td->td_retval[0] = p->p_pid; if (status) *status = p->p_xstat; /* convert to int */