Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Dec 2012 01:13:07 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r243962 - in stable/9/sys: fs/nfsclient kern sys
Message-ID:  <201212070113.qB71D82o072090@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Dec  7 01:13:07 2012
New Revision: 243962
URL: http://svnweb.freebsd.org/changeset/base/243962

Log:
  MFC r243142:
  In pget(9), if PGET_NOTWEXIT flag is not specified, also search the
  zombie list for the pid. This allows several kern.proc sysctls to
  report useful information for zombies.
  
  Hold the allproc_lock around all searches instead of relocking it.
  Remove private pfind_locked() from the new nfs client code.
  
  MFC r243528 (by pjd):
  Look for zombie process only if we were given process id.

Modified:
  stable/9/sys/fs/nfsclient/nfs_clport.c
  stable/9/sys/kern/kern_proc.c
  stable/9/sys/sys/proc.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/fs/   (props changed)

Modified: stable/9/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- stable/9/sys/fs/nfsclient/nfs_clport.c	Fri Dec  7 00:46:43 2012	(r243961)
+++ stable/9/sys/fs/nfsclient/nfs_clport.c	Fri Dec  7 01:13:07 2012	(r243962)
@@ -1150,31 +1150,6 @@ nfscl_maperr(struct thread *td, int erro
 }
 
 /*
- * Locate a process by number; return only "live" processes -- i.e., neither
- * zombies nor newly born but incompletely initialized processes.  By not
- * returning processes in the PRS_NEW state, we allow callers to avoid
- * testing for that condition to avoid dereferencing p_ucred, et al.
- * Identical to pfind() in kern_proc.c, except it assume the list is
- * already locked.
- */
-static struct proc *
-pfind_locked(pid_t pid)
-{
-	struct proc *p;
-
-	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;
-		}
-	return (p);
-}
-
-/*
  * Check to see if the process for this owner exists. Return 1 if it doesn't
  * and 0 otherwise.
  */

Modified: stable/9/sys/kern/kern_proc.c
==============================================================================
--- stable/9/sys/kern/kern_proc.c	Fri Dec  7 00:46:43 2012	(r243961)
+++ stable/9/sys/kern/kern_proc.c	Fri Dec  7 01:13:07 2012	(r243962)
@@ -137,6 +137,7 @@ static void proc_dtor(void *mem, int siz
 static int proc_init(void *mem, int size, int flags);
 static void proc_fini(void *mem, int size);
 static void pargs_free(struct pargs *pa);
+static struct proc *zpfind_locked(pid_t pid);
 
 /*
  * Other process lists
@@ -284,20 +285,13 @@ inferior(p)
 	return (1);
 }
 
-/*
- * Locate a process by number; return only "live" processes -- i.e., neither
- * zombies nor newly born but incompletely initialized processes.  By not
- * returning processes in the PRS_NEW state, we allow callers to avoid
- * testing for that condition to avoid dereferencing p_ucred, et al.
- */
 struct proc *
-pfind(pid)
-	register pid_t pid;
+pfind_locked(pid_t pid)
 {
-	register struct proc *p;
+	struct proc *p;
 
-	sx_slock(&allproc_lock);
-	LIST_FOREACH(p, PIDHASH(pid), p_hash)
+	sx_assert(&allproc_lock, SX_LOCKED);
+	LIST_FOREACH(p, PIDHASH(pid), p_hash) {
 		if (p->p_pid == pid) {
 			PROC_LOCK(p);
 			if (p->p_state == PRS_NEW) {
@@ -306,17 +300,34 @@ pfind(pid)
 			}
 			break;
 		}
+	}
+	return (p);
+}
+
+/*
+ * Locate a process by number; return only "live" processes -- i.e., neither
+ * zombies nor newly born but incompletely initialized processes.  By not
+ * returning processes in the PRS_NEW state, we allow callers to avoid
+ * testing for that condition to avoid dereferencing p_ucred, et al.
+ */
+struct proc *
+pfind(pid_t pid)
+{
+	struct proc *p;
+
+	sx_slock(&allproc_lock);
+	p = pfind_locked(pid);
 	sx_sunlock(&allproc_lock);
 	return (p);
 }
 
 static struct proc *
-pfind_tid(pid_t tid)
+pfind_tid_locked(pid_t tid)
 {
 	struct proc *p;
 	struct thread *td;
 
-	sx_slock(&allproc_lock);
+	sx_assert(&allproc_lock, SX_LOCKED);
 	FOREACH_PROC_IN_SYSTEM(p) {
 		PROC_LOCK(p);
 		if (p->p_state == PRS_NEW) {
@@ -330,7 +341,6 @@ pfind_tid(pid_t tid)
 		PROC_UNLOCK(p);
 	}
 found:
-	sx_sunlock(&allproc_lock);
 	return (p);
 }
 
@@ -364,12 +374,17 @@ pget(pid_t pid, int flags, struct proc *
 	struct proc *p;
 	int error;
 
-	if (pid <= PID_MAX)
-		p = pfind(pid);
-	else if ((flags & PGET_NOTID) == 0)
-		p = pfind_tid(pid);
-	else
+	sx_slock(&allproc_lock);
+	if (pid <= PID_MAX) {
+		p = pfind_locked(pid);
+		if (p == NULL && (flags & PGET_NOTWEXIT) == 0)
+			p = zpfind_locked(pid);
+	} else if ((flags & PGET_NOTID) == 0) {
+		p = pfind_tid_locked(pid);
+	} else {
 		p = NULL;
+	}
+	sx_sunlock(&allproc_lock);
 	if (p == NULL)
 		return (ESRCH);
 	if ((flags & PGET_CANSEE) != 0) {
@@ -1046,6 +1061,21 @@ pstats_free(struct pstats *ps)
 	free(ps, M_SUBPROC);
 }
 
+static struct proc *
+zpfind_locked(pid_t pid)
+{
+	struct proc *p;
+
+	sx_assert(&allproc_lock, SX_LOCKED);
+	LIST_FOREACH(p, &zombproc, p_list) {
+		if (p->p_pid == pid) {
+			PROC_LOCK(p);
+			break;
+		}
+	}
+	return (p);
+}
+
 /*
  * Locate a zombie process by number
  */
@@ -1055,11 +1085,7 @@ zpfind(pid_t pid)
 	struct proc *p;
 
 	sx_slock(&allproc_lock);
-	LIST_FOREACH(p, &zombproc, p_list)
-		if (p->p_pid == pid) {
-			PROC_LOCK(p);
-			break;
-		}
+	p = zpfind_locked(pid);
 	sx_sunlock(&allproc_lock);
 	return (p);
 }

Modified: stable/9/sys/sys/proc.h
==============================================================================
--- stable/9/sys/sys/proc.h	Fri Dec  7 00:46:43 2012	(r243961)
+++ stable/9/sys/sys/proc.h	Fri Dec  7 01:13:07 2012	(r243962)
@@ -835,6 +835,7 @@ extern struct proc *initproc, *pageproc;
 extern struct uma_zone *proc_zone;
 
 struct	proc *pfind(pid_t);		/* Find process by id. */
+struct	proc *pfind_locked(pid_t pid);
 struct	pgrp *pgfind(pid_t);		/* Find process group by id. */
 struct	proc *zpfind(pid_t);		/* Find zombie process by id. */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212070113.qB71D82o072090>