Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Nov 2012 08:25:06 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r243142 - in head/sys: fs/nfsclient kern sys
Message-ID:  <201211160825.qAG8P6v6047507@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Nov 16 08:25:06 2012
New Revision: 243142
URL: http://svnweb.freebsd.org/changeset/base/243142

Log:
  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.
  
  Requested and reviewed by:	pjd
  Tested by:	pho
  MFC after:	3 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clport.c
  head/sys/kern/kern_proc.c
  head/sys/sys/proc.h

Modified: head/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clport.c	Fri Nov 16 07:30:38 2012	(r243141)
+++ head/sys/fs/nfsclient/nfs_clport.c	Fri Nov 16 08:25:06 2012	(r243142)
@@ -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: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c	Fri Nov 16 07:30:38 2012	(r243141)
+++ head/sys/kern/kern_proc.c	Fri Nov 16 08:25:06 2012	(r243142)
@@ -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,16 @@ pget(pid_t pid, int flags, struct proc *
 	struct proc *p;
 	int error;
 
+	sx_slock(&allproc_lock);
 	if (pid <= PID_MAX)
-		p = pfind(pid);
+		p = pfind_locked(pid);
 	else if ((flags & PGET_NOTID) == 0)
-		p = pfind_tid(pid);
+		p = pfind_tid_locked(pid);
 	else
 		p = NULL;
+	if (p == NULL && (flags & PGET_NOTWEXIT) == 0)
+		p = zpfind_locked(pid);
+	sx_sunlock(&allproc_lock);
 	if (p == NULL)
 		return (ESRCH);
 	if ((flags & PGET_CANSEE) != 0) {
@@ -1044,6 +1058,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
  */
@@ -1053,11 +1082,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: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Fri Nov 16 07:30:38 2012	(r243141)
+++ head/sys/sys/proc.h	Fri Nov 16 08:25:06 2012	(r243142)
@@ -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?201211160825.qAG8P6v6047507>