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. */
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to