kernel - Fix p->p_lock race and remove unused procedures
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 10 Nov 2011 20:25:09 +0000 (12:25 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 10 Nov 2011 20:25:09 +0000 (12:25 -0800)
* Remove vm_waitproc() (move its vmspace_exitfree() call to the one place
  that calls vm_waitproc()).

* Remove cpu_proc_wait(), which only called pmap_dispose_proc().

* Remove pmap_dispose_proc(), which only had an (incorrect) assertion in it
  and otherwise did nothing.

* Wait for the p->p_lock count to drop to zero before calling
  vmspace_exitfree(), and then wait again afterwords now that there
  are absolutely no possible references to (p) left.

13 files changed:
sys/kern/kern_exit.c
sys/platform/pc32/i386/pmap.c
sys/platform/pc32/i386/vm_machdep.c
sys/platform/pc64/x86_64/pmap.c
sys/platform/pc64/x86_64/vm_machdep.c
sys/platform/vkernel/i386/vm_machdep.c
sys/platform/vkernel/platform/pmap.c
sys/platform/vkernel64/platform/pmap.c
sys/platform/vkernel64/x86_64/vm_machdep.c
sys/sys/proc.h
sys/vm/pmap.h
sys/vm/vm_extern.h
sys/vm/vm_glue.c

index a684ad6..e01d662 100644 (file)
@@ -947,17 +947,20 @@ loop:
                                ps = NULL;
                        }
 
-                       vm_waitproc(p);
-
                        /*
-                        * Temporary refs may still have been acquired while
-                        * we removed the process, make sure they are all
-                        * gone before kfree()ing.  Now that the process has
-                        * been removed from all lists and all references to
-                        * it have gone away, no new refs can occur.
+                        * Our exitingcount was incremented when the process
+                        * became a zombie, now that the process has been
+                        * removed from (almost) all lists we should be able
+                        * to safely destroy its vmspace.  Wait for any current
+                        * holders to go away (so the vmspace remains stable),
+                        * then scrap it.
                         */
                        while (p->p_lock)
                                tsleep(p, 0, "reap4", hz);
+                       vmspace_exitfree(p);
+                       while (p->p_lock)
+                               tsleep(p, 0, "reap5", hz);
+
                        kfree(p, M_PROC);
                        atomic_add_int(&nprocs, -1);
                        error = 0;
index 8a8c95f..5566a1b 100644 (file)
@@ -1013,16 +1013,6 @@ pmap_init_proc(struct proc *p)
 {
 }
 
-/*
- * Dispose the UPAGES for a process that has exited.
- * This routine directly impacts the exit perf of a process.
- */
-void
-pmap_dispose_proc(struct proc *p)
-{
-       KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
-}
-
 /***************************************************
  * Page table page management routines.....
  ***************************************************/
index 13ace21..e009c12 100644 (file)
@@ -326,17 +326,6 @@ cpu_thread_exit(void)
        panic("cpu_exit");
 }
 
-/*
- * Process Reaper.  Called after the caller has acquired the thread's
- * rwlock and removed it from the reap list.
- */
-void
-cpu_proc_wait(struct proc *p)
-{
-       /* drop per-process resources */
-       pmap_dispose_proc(p);
-}
-
 #ifdef notyet
 static void
 setredzone(u_short *pte, caddr_t vaddr)
index 68e71b8..8781a2b 100644 (file)
@@ -1294,16 +1294,6 @@ pmap_init_proc(struct proc *p)
 {
 }
 
-/*
- * Dispose the UPAGES for a process that has exited.
- * This routine directly impacts the exit perf of a process.
- */
-void
-pmap_dispose_proc(struct proc *p)
-{
-       KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
-}
-
 /*
  * Initialize pmap0/vmspace0.  This pmap is not added to pmap_list because
  * it, and IdlePTD, represents the template used to update all other pmaps.
index 4927e1c..1e46db3 100644 (file)
@@ -294,17 +294,6 @@ cpu_thread_exit(void)
        panic("cpu_thread_exit: lwkt_switch() unexpectedly returned");
 }
 
-/*
- * Process Reaper.  Called after the caller has acquired the thread's
- * rwlock and removed it from the reap list.
- */
-void
-cpu_proc_wait(struct proc *p)
-{
-       /* drop per-process resources */
-       pmap_dispose_proc(p);
-}
-
 void
 cpu_reset(void)
 {
index 23aa9fd..ddc7df6 100644 (file)
@@ -326,17 +326,6 @@ cpu_thread_exit(void)
        panic("cpu_exit");
 }
 
-/*
- * Process Reaper.  Called after the caller has acquired the thread's
- * rwlock and removed it from the reap list.
- */
-void
-cpu_proc_wait(struct proc *p)
-{
-       /* drop per-process resources */
-       pmap_dispose_proc(p);
-}
-
 #ifdef notyet
 static void
 setredzone(u_short *pte, caddr_t vaddr)
index 8bfe86c..52abbc6 100644 (file)
@@ -886,16 +886,6 @@ pmap_init_proc(struct proc *p)
 {
 }
 
-/*
- * Destroy the UPAGES for a process that has exited and disassociate
- * the process from its thread.
- */
-void
-pmap_dispose_proc(struct proc *p)
-{
-       KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
-}
-
 /*
  * We pre-allocate all page table pages for kernel virtual memory so
  * this routine will only be called if KVM has been exhausted.
index 0150048..cce3de4 100644 (file)
@@ -898,16 +898,6 @@ pmap_init_proc(struct proc *p)
 {
 }
 
-/*
- * Dispose the UPAGES for a process that has exited.
- * This routine directly impacts the exit perf of a process.
- */
-void
-pmap_dispose_proc(struct proc *p)
-{
-       KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
-}
-
 /***************************************************
  * Page table page management routines.....
  ***************************************************/
index 2ff6882..dcab929 100644 (file)
@@ -295,17 +295,6 @@ cpu_thread_exit(void)
        panic("cpu_thread_exit: lwkt_switch() unexpectedly returned");
 }
 
-/*
- * Process Reaper.  Called after the caller has acquired the thread's
- * rwlock and removed it from the reap list.
- */
-void
-cpu_proc_wait(struct proc *p)
-{
-       /* drop per-process resources */
-       pmap_dispose_proc(p);
-}
-
 int
 grow_stack(struct proc *p, u_long sp)
 {
index 15ba8ef..61029f8 100644 (file)
@@ -542,7 +542,6 @@ void        cpu_set_thread_handler(struct thread *td, void (*retfunc)(void), void *func
 int    fork1 (struct lwp *, int, struct proc **);
 void   start_forked_proc (struct lwp *, struct proc *);
 int    trace_req (struct proc *);
-void   cpu_proc_wait (struct proc *);
 void   cpu_thread_wait (struct thread *);
 void   setsugid (void);
 void   faultin (struct proc *p);
index 1f3ae7a..97c41c5 100644 (file)
@@ -192,7 +192,6 @@ int          pmap_prefault_ok (pmap_t, vm_offset_t);
 int             pmap_mincore (pmap_t pmap, vm_offset_t addr);
 void            pmap_init_proc (struct proc *);
 void            pmap_init_thread (struct thread *td);
-void            pmap_dispose_proc (struct proc *p);
 void            pmap_replacevm (struct proc *, struct vmspace *, int);
 void            pmap_setlwpvm (struct lwp *, struct vmspace *);
 
index f1c3360..a9b9b43 100644 (file)
@@ -98,7 +98,6 @@ void vm_fault_unwire (vm_map_t, vm_map_entry_t);
 int vm_fault_wire (vm_map_t, vm_map_entry_t, boolean_t);
 void vm_fork (struct proc *, struct proc *, int);
 void vm_fault_ratecheck(void);
-void vm_waitproc (struct proc *);
 int vm_test_nominal (void);
 void vm_wait_nominal (void);
 void vm_init_limits(struct proc *);
index 224dc69..6c2ac8c 100644 (file)
@@ -265,20 +265,6 @@ vm_fork(struct proc *p1, struct proc *p2, int flags)
        pmap_init_proc(p2);
 }
 
-/*
- * Called after process has been wait(2)'ed apon and is being reaped.
- * The idea is to reclaim resources that we could not reclaim while  
- * the process was still executing.
- *
- * No requirements.
- */
-void
-vm_waitproc(struct proc *p)
-{
-       cpu_proc_wait(p);
-       vmspace_exitfree(p);    /* and clean-out the vmspace */
-}
-
 /*
  * Set default limits for VM system.  Call during proc0's initialization.
  *