From owner-svn-src-stable-8@FreeBSD.ORG Tue Jun 7 21:48:37 2011 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 447101065674; Tue, 7 Jun 2011 21:48:37 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3309A8FC17; Tue, 7 Jun 2011 21:48:37 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p57LmbH3001965; Tue, 7 Jun 2011 21:48:37 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p57LmaQC001956; Tue, 7 Jun 2011 21:48:36 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201106072148.p57LmaQC001956@svn.freebsd.org> From: John Baldwin Date: Tue, 7 Jun 2011 21:48:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222839 - in stable/8/sys: compat/linprocfs fs/nfsclient kern vm X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jun 2011 21:48:37 -0000 Author: jhb Date: Tue Jun 7 21:48:36 2011 New Revision: 222839 URL: http://svn.freebsd.org/changeset/base/222839 Log: MFC 219968: Fix some locking nits with the p_state field of struct proc: - Hold the proc lock while changing the state from PRS_NEW to PRS_NORMAL in fork to honor the locking requirements. While here, expand the scope of the PROC_LOCK() on the new process (p2) to avoid some LORs. Previously the code was locking the new child process (p2) after it had locked the parent process (p1). However, when locking two processes, the safe order is to lock the child first, then the parent. - Fix various places that were checking p_state against PRS_NEW without having the process locked to use PROC_LOCK(). Every place was already locking the process, just after the PRS_NEW check. - Remove or reduce the use of PROC_SLOCK() for places that were checking p_state against PRS_NEW. The PROC_LOCK() alone is sufficient for reading the current state. Modified: stable/8/sys/compat/linprocfs/linprocfs.c stable/8/sys/fs/nfsclient/nfs_clport.c stable/8/sys/kern/kern_descrip.c stable/8/sys/kern/kern_fork.c stable/8/sys/kern/kern_proc.c stable/8/sys/kern/kern_resource.c stable/8/sys/vm/vm_meter.c stable/8/sys/vm/vm_pageout.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/compat/linprocfs/linprocfs.c ============================================================================== --- stable/8/sys/compat/linprocfs/linprocfs.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/compat/linprocfs/linprocfs.c Tue Jun 7 21:48:36 2011 (r222839) @@ -739,7 +739,6 @@ linprocfs_doprocstatus(PFS_FILL_ARGS) if (P_SHOULDSTOP(p)) { state = "T (stopped)"; } else { - PROC_SLOCK(p); switch(p->p_state) { case PRS_NEW: state = "I (idle)"; @@ -769,7 +768,6 @@ linprocfs_doprocstatus(PFS_FILL_ARGS) state = "? (unknown)"; break; } - PROC_SUNLOCK(p); } fill_kinfo_proc(p, &kp); Modified: stable/8/sys/fs/nfsclient/nfs_clport.c ============================================================================== --- stable/8/sys/fs/nfsclient/nfs_clport.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/fs/nfsclient/nfs_clport.c Tue Jun 7 21:48:36 2011 (r222839) @@ -1126,11 +1126,11 @@ pfind_locked(pid_t pid) LIST_FOREACH(p, PIDHASH(pid), p_hash) if (p->p_pid == pid) { + PROC_LOCK(p); if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); p = NULL; - break; } - PROC_LOCK(p); break; } return (p); Modified: stable/8/sys/kern/kern_descrip.c ============================================================================== --- stable/8/sys/kern/kern_descrip.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/kern/kern_descrip.c Tue Jun 7 21:48:36 2011 (r222839) @@ -2643,9 +2643,11 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS) xf.xf_size = sizeof(xf); sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - if (p->p_state == PRS_NEW) - continue; PROC_LOCK(p); + if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); + continue; + } if (p_cansee(req->td, p) != 0) { PROC_UNLOCK(p); continue; Modified: stable/8/sys/kern/kern_fork.c ============================================================================== --- stable/8/sys/kern/kern_fork.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/kern/kern_fork.c Tue Jun 7 21:48:36 2011 (r222839) @@ -722,10 +722,13 @@ again: /* * Set the child start time and mark the process as being complete. */ + PROC_LOCK(p2); + PROC_LOCK(p1); microuptime(&p2->p_stats->p_start); PROC_SLOCK(p2); p2->p_state = PRS_NORMAL; PROC_SUNLOCK(p2); + #ifdef KDTRACE_HOOKS /* * Tell the DTrace fasttrap provider about the new process @@ -733,16 +736,9 @@ again: * p_state is PRS_NORMAL since the fasttrap module will use pfind() * later on. */ - if (dtrace_fasttrap_fork) { - PROC_LOCK(p1); - PROC_LOCK(p2); + if (dtrace_fasttrap_fork) dtrace_fasttrap_fork(p1, p2); - PROC_UNLOCK(p2); - PROC_UNLOCK(p1); - } #endif - - PROC_LOCK(p1); if ((p1->p_flag & (P_TRACED | P_FOLLOWFORK)) == (P_TRACED | P_FOLLOWFORK)) { /* @@ -754,12 +750,11 @@ again: */ td->td_dbgflags |= TDB_FORK; td->td_dbg_forked = p2->p_pid; - PROC_LOCK(p2); td2->td_dbgflags |= TDB_STOPATFORK; _PHOLD(p2); p2_held = 1; - PROC_UNLOCK(p2); } + PROC_UNLOCK(p2); if ((flags & RFSTOPPED) == 0) { /* * If RFSTOPPED not requested, make child runnable and Modified: stable/8/sys/kern/kern_proc.c ============================================================================== --- stable/8/sys/kern/kern_proc.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/kern/kern_proc.c Tue Jun 7 21:48:36 2011 (r222839) @@ -290,11 +290,11 @@ pfind(pid) sx_slock(&allproc_lock); LIST_FOREACH(p, PIDHASH(pid), p_hash) if (p->p_pid == pid) { + PROC_LOCK(p); if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); p = NULL; - break; } - PROC_LOCK(p); break; } sx_sunlock(&allproc_lock); @@ -750,7 +750,6 @@ fill_kinfo_proc_only(struct proc *p, str kp->ki_sigcatch = ps->ps_sigcatch; mtx_unlock(&ps->ps_mtx); } - PROC_SLOCK(p); if (p->p_state != PRS_NEW && p->p_state != PRS_ZOMBIE && p->p_vmspace != NULL) { @@ -776,6 +775,7 @@ fill_kinfo_proc_only(struct proc *p, str kp->ki_swtime = (ticks - p->p_swtick) / hz; kp->ki_pid = p->p_pid; kp->ki_nice = p->p_nice; + PROC_SLOCK(p); rufetch(p, &kp->ki_rusage); kp->ki_runtime = cputick2usec(p->p_rux.rux_runtime); PROC_SUNLOCK(p); @@ -1208,13 +1208,11 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) /* * Skip embryonic processes. */ - PROC_SLOCK(p); + PROC_LOCK(p); if (p->p_state == PRS_NEW) { - PROC_SUNLOCK(p); + PROC_UNLOCK(p); continue; } - PROC_SUNLOCK(p); - PROC_LOCK(p); KASSERT(p->p_ucred != NULL, ("process credential is NULL for non-NEW proc")); /* Modified: stable/8/sys/kern/kern_resource.c ============================================================================== --- stable/8/sys/kern/kern_resource.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/kern/kern_resource.c Tue Jun 7 21:48:36 2011 (r222839) @@ -142,11 +142,9 @@ getpriority(td, uap) uap->who = td->td_ucred->cr_uid; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - /* Do not bother to check PRS_NEW processes */ - if (p->p_state == PRS_NEW) - continue; PROC_LOCK(p); - if (p_cansee(td, p) == 0 && + if (p->p_state == PRS_NORMAL && + p_cansee(td, p) == 0 && p->p_ucred->cr_uid == uap->who) { if (p->p_nice < low) low = p->p_nice; Modified: stable/8/sys/vm/vm_meter.c ============================================================================== --- stable/8/sys/vm/vm_meter.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/vm/vm_meter.c Tue Jun 7 21:48:36 2011 (r222839) @@ -132,15 +132,12 @@ vmtotal(SYSCTL_HANDLER_ARGS) if (p->p_flag & P_SYSTEM) continue; PROC_LOCK(p); - PROC_SLOCK(p); switch (p->p_state) { case PRS_NEW: - PROC_SUNLOCK(p); PROC_UNLOCK(p); continue; break; default: - PROC_SUNLOCK(p); FOREACH_THREAD_IN_PROC(p, td) { thread_lock(td); switch (td->td_state) { Modified: stable/8/sys/vm/vm_pageout.c ============================================================================== --- stable/8/sys/vm/vm_pageout.c Tue Jun 7 21:16:02 2011 (r222838) +++ stable/8/sys/vm/vm_pageout.c Tue Jun 7 21:48:36 2011 (r222839) @@ -1212,7 +1212,8 @@ vm_pageout_oom(int shortage) /* * If this is a system, protected or killed process, skip it. */ - if ((p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) || + if (p->p_state != PRS_NORMAL || + (p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) || (p->p_pid == 1) || P_KILLED(p) || ((p->p_pid < 48) && (swap_pager_avail != 0))) { PROC_UNLOCK(p); @@ -1573,7 +1574,8 @@ vm_daemon() * looked at this process, skip it. */ PROC_LOCK(p); - if (p->p_flag & (P_INEXEC | P_SYSTEM | P_WEXIT)) { + if (p->p_state != PRS_NORMAL || + p->p_flag & (P_INEXEC | P_SYSTEM | P_WEXIT)) { PROC_UNLOCK(p); continue; }