From e22b17d7f557c0e9481bc8962a5ac417e883e11a Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 10 Nov 2011 12:25:09 -0800 Subject: [PATCH] kernel - Fix p->p_lock race and remove unused procedures * 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. --- sys/kern/kern_exit.c | 17 ++++++++++------- sys/platform/pc32/i386/pmap.c | 10 ---------- sys/platform/pc32/i386/vm_machdep.c | 11 ----------- sys/platform/pc64/x86_64/pmap.c | 10 ---------- sys/platform/pc64/x86_64/vm_machdep.c | 11 ----------- sys/platform/vkernel/i386/vm_machdep.c | 11 ----------- sys/platform/vkernel/platform/pmap.c | 10 ---------- sys/platform/vkernel64/platform/pmap.c | 10 ---------- sys/platform/vkernel64/x86_64/vm_machdep.c | 11 ----------- sys/sys/proc.h | 1 - sys/vm/pmap.h | 1 - sys/vm/vm_extern.h | 1 - sys/vm/vm_glue.c | 14 -------------- 13 files changed, 10 insertions(+), 108 deletions(-) diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a684ad68ce..e01d662121 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -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; diff --git a/sys/platform/pc32/i386/pmap.c b/sys/platform/pc32/i386/pmap.c index 8a8c95f44c..5566a1b8b9 100644 --- a/sys/platform/pc32/i386/pmap.c +++ b/sys/platform/pc32/i386/pmap.c @@ -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..... ***************************************************/ diff --git a/sys/platform/pc32/i386/vm_machdep.c b/sys/platform/pc32/i386/vm_machdep.c index 13ace21f91..e009c12cbe 100644 --- a/sys/platform/pc32/i386/vm_machdep.c +++ b/sys/platform/pc32/i386/vm_machdep.c @@ -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) diff --git a/sys/platform/pc64/x86_64/pmap.c b/sys/platform/pc64/x86_64/pmap.c index 68e71b82a1..8781a2b664 100644 --- a/sys/platform/pc64/x86_64/pmap.c +++ b/sys/platform/pc64/x86_64/pmap.c @@ -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. diff --git a/sys/platform/pc64/x86_64/vm_machdep.c b/sys/platform/pc64/x86_64/vm_machdep.c index 4927e1ce82..1e46db3db9 100644 --- a/sys/platform/pc64/x86_64/vm_machdep.c +++ b/sys/platform/pc64/x86_64/vm_machdep.c @@ -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) { diff --git a/sys/platform/vkernel/i386/vm_machdep.c b/sys/platform/vkernel/i386/vm_machdep.c index 23aa9fd9d7..ddc7df6b57 100644 --- a/sys/platform/vkernel/i386/vm_machdep.c +++ b/sys/platform/vkernel/i386/vm_machdep.c @@ -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) diff --git a/sys/platform/vkernel/platform/pmap.c b/sys/platform/vkernel/platform/pmap.c index 8bfe86c6de..52abbc60fa 100644 --- a/sys/platform/vkernel/platform/pmap.c +++ b/sys/platform/vkernel/platform/pmap.c @@ -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. diff --git a/sys/platform/vkernel64/platform/pmap.c b/sys/platform/vkernel64/platform/pmap.c index 0150048d64..cce3de437d 100644 --- a/sys/platform/vkernel64/platform/pmap.c +++ b/sys/platform/vkernel64/platform/pmap.c @@ -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..... ***************************************************/ diff --git a/sys/platform/vkernel64/x86_64/vm_machdep.c b/sys/platform/vkernel64/x86_64/vm_machdep.c index 2ff688276a..dcab9292dd 100644 --- a/sys/platform/vkernel64/x86_64/vm_machdep.c +++ b/sys/platform/vkernel64/x86_64/vm_machdep.c @@ -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) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 15ba8ef5d9..61029f8a33 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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); diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 1f3ae7a273..97c41c551b 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -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 *); diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index f1c3360c70..a9b9b4332f 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -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 *); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 224dc696b8..6c2ac8caf3 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -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. * -- 2.41.0