diff options
author | 2000-06-05 11:02:48 +0000 | |
---|---|---|
committer | 2000-06-05 11:02:48 +0000 | |
commit | f69f8c5290df53e8a3d62b3430621995269d7588 (patch) | |
tree | 8d38b62565a43a00307544c3dddf85337bbb6e96 | |
parent | fix datasheet url (diff) | |
download | wireguard-openbsd-f69f8c5290df53e8a3d62b3430621995269d7588.tar.xz wireguard-openbsd-f69f8c5290df53e8a3d62b3430621995269d7588.zip |
Changes to exit handling.
cpu_exit no longer frees the vmspace and u-area. This is now handled by a
separate kernel thread "reaper". This is to avoid sleeping locks in the
critical path of cpu_exit where we're not allowed to sleep.
From NetBSD
35 files changed, 249 insertions, 206 deletions
diff --git a/sys/arch/alpha/alpha/locore.s b/sys/arch/alpha/alpha/locore.s index 5567c507053..3ec60e37fec 100644 --- a/sys/arch/alpha/alpha/locore.s +++ b/sys/arch/alpha/alpha/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.11 1999/11/13 21:33:44 deraadt Exp $ */ +/* $OpenBSD: locore.s,v 1.12 2000/06/05 11:02:54 art Exp $ */ /* $NetBSD: locore.s,v 1.27 1996/12/03 19:54:16 cgd Exp $ */ /* @@ -833,11 +833,9 @@ LEAF(switch_exit, 1) * the saved regs. */ - /* blow away the old user struct */ - ldq a0, kernel_map - ldq a1, P_ADDR(s2) - ldiq a2, (UPAGES * NBPG) - CALL(kmem_free) + /* Schedule the vmspace and stack to be freed. */ + mov s2, a0 + CALL(exit2) /* and jump into the middle of cpu_switch. */ #ifdef NEW_PMAP diff --git a/sys/arch/alpha/alpha/vm_machdep.c b/sys/arch/alpha/alpha/vm_machdep.c index 9009bc0cbe2..fe182b2fe0e 100644 --- a/sys/arch/alpha/alpha/vm_machdep.c +++ b/sys/arch/alpha/alpha/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.12 1999/09/14 11:41:18 kstailey Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.13 2000/06/05 11:02:55 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.21 1996/11/13 21:13:15 cgd Exp $ */ /* @@ -116,8 +116,6 @@ cpu_exit(p) if (p == fpcurproc) fpcurproc = NULL; - vmspace_free(p->p_vmspace); - (void) splhigh(); switch_exit(p); /* NOTREACHED */ diff --git a/sys/arch/amiga/amiga/locore.s b/sys/arch/amiga/amiga/locore.s index 5db4275ae7c..dd604cc4bb4 100644 --- a/sys/arch/amiga/amiga/locore.s +++ b/sys/arch/amiga/amiga/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.28 2000/05/28 03:55:21 art Exp $ */ +/* $OpenBSD: locore.s,v 1.29 2000/06/05 11:02:55 art Exp $ */ /* $NetBSD: locore.s,v 1.89 1997/07/17 16:22:54 is Exp $ */ /* @@ -1223,16 +1223,10 @@ ENTRY(switch_exit) movl #nullpcb,_curpcb | save state into garbage pcb lea tmpstk,sp | goto a tmp stack - /* Free old process's user area. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address u-area of process - movl _kernel_map,sp@- | map it was allocated in -#if defined(UVM) - jbsr _uvm_km_free | deallocate it -#else - jbsr _kmem_free | deallocate it -#endif - lea sp@(12),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args jra _cpu_switch diff --git a/sys/arch/amiga/amiga/vm_machdep.c b/sys/arch/amiga/amiga/vm_machdep.c index c9d782fe27a..70490213a40 100644 --- a/sys/arch/amiga/amiga/vm_machdep.c +++ b/sys/arch/amiga/amiga/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.13 2000/05/28 03:55:21 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.14 2000/06/05 11:02:56 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.30 1997/05/19 10:14:50 veego Exp $ */ /* @@ -151,12 +151,7 @@ void cpu_exit(p) struct proc *p; { -#if defined(UVM) - uvmspace_free(p->p_vmspace); -#else - vmspace_free(p->p_vmspace); -#endif - + (void)splhigh(); #if defined(UVM) uvmexp.swtch++; diff --git a/sys/arch/hp300/hp300/locore.s b/sys/arch/hp300/hp300/locore.s index 77ecd302818..5e0e831126c 100644 --- a/sys/arch/hp300/hp300/locore.s +++ b/sys/arch/hp300/hp300/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.21 1998/09/06 20:09:59 millert Exp $ */ +/* $OpenBSD: locore.s,v 1.22 2000/06/05 11:02:57 art Exp $ */ /* $NetBSD: locore.s,v 1.79 1997/09/12 08:41:55 mycroft Exp $ */ /* @@ -1221,12 +1221,10 @@ ENTRY(switch_exit) movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb) lea _ASM_LABEL(tmpstk),sp | goto a tmp stack - /* Free old process's resources. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address of process's u-area - movl _C_LABEL(kernel_map),sp@- | map it was allocated in - jbsr _C_LABEL(kmem_free) | deallocate it - lea sp@(12),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args jra _C_LABEL(cpu_switch) diff --git a/sys/arch/hp300/hp300/vm_machdep.c b/sys/arch/hp300/hp300/vm_machdep.c index 337b16b1743..32c00e44189 100644 --- a/sys/arch/hp300/hp300/vm_machdep.c +++ b/sys/arch/hp300/hp300/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.14 1999/09/03 18:00:44 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.15 2000/06/05 11:02:57 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.37 1997/05/26 00:27:43 thorpej Exp $ */ /* @@ -134,8 +134,6 @@ cpu_exit(p) struct proc *p; { - vmspace_free(p->p_vmspace); - (void) splimp(); cnt.v_swtch++; switch_exit(p); diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index 5600f8c33c3..05c0f3dc1c0 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.50 2000/05/01 00:43:41 mickey Exp $ */ +/* $OpenBSD: locore.s,v 1.51 2000/06/05 11:02:54 art Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -1943,24 +1943,12 @@ ENTRY(switch_exit) /* Interrupts are okay again. */ sti - /* Thoroughly nuke the old process's resources. */ - pushl P_ADDR(%edi) - call _tss_free - pushl P_VMSPACE(%edi) -#if defined(UVM) - call _C_LABEL(uvmspace_free) -#else - call _vmspace_free -#endif - pushl $USPACE - pushl P_ADDR(%edi) - pushl _kernel_map -#if defined(UVM) - call _C_LABEL(uvm_km_free) -#else - call _kmem_free -#endif - addl $20,%esp + /* + * Schedule the dead process's vmspace and stack to be freed. + */ + pushl %edi /* exit2(p) */ + call _C_LABEL(exit2) + addl $4,%esp /* Jump into cpu_switch() with the right state. */ movl %ebx,%esi diff --git a/sys/arch/i386/i386/vm_machdep.c b/sys/arch/i386/i386/vm_machdep.c index 78c3e5fa531..5ba85422128 100644 --- a/sys/arch/i386/i386/vm_machdep.c +++ b/sys/arch/i386/i386/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.17 1999/08/17 10:32:16 niklas Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.18 2000/06/05 11:02:54 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.61 1996/05/03 19:42:35 christos Exp $ */ /*- @@ -206,29 +206,12 @@ void cpu_exit(p) register struct proc *p; { -#ifdef USER_LDT - struct pcb *pcb; -#endif - struct vmspace *vm; - #if NNPX > 0 /* If we were using the FPU, forget about it. */ if (npxproc == p) npxproc = 0; #endif -#ifdef USER_LDT - pcb = &p->p_addr->u_pcb; - if (pcb->pcb_flags & PCB_USER_LDT) - i386_user_cleanup(pcb); -#endif - - vm = p->p_vmspace; -#if !defined(UVM) - if (vm->vm_refcnt == 1) - vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS); -#endif - #if defined(UVM) uvmexp.swtch++; #else @@ -237,6 +220,20 @@ cpu_exit(p) switch_exit(p); } +void +cpu_wait(p) + struct proc *p; +{ + struct pcb *pcb; + + pcb = &p->p_addr->u_pcb; +#ifdef USER_LDT + if (pcb->pcb_flags & PCB_USER_LDT) + i386_user_cleanup(pcb); +#endif + tss_free(pcb); +} + /* * Dump the machine specific segment at the start of a core dump. */ diff --git a/sys/arch/kbus/include/pmap.h b/sys/arch/kbus/include/pmap.h index 228516d859a..7f338b611d8 100644 --- a/sys/arch/kbus/include/pmap.h +++ b/sys/arch/kbus/include/pmap.h @@ -294,7 +294,8 @@ void pmap_bootstrap __P((vm_offset_t firstaddr)); void pmap_disp_va __P((pmap_t pmap, vm_offset_t va)); vm_offset_t pmap_map __P((vm_offset_t, vm_offset_t, vm_offset_t, int)); struct user; -void switchexit __P((vm_map_t, struct user *, int)); +struct proc; +void switchexit __P((struct proc *)); #endif /* _KERNEL */ #endif /* !_LOCORE */ diff --git a/sys/arch/kbus/kbus/locore.s b/sys/arch/kbus/kbus/locore.s index 7c63f5c7938..97945eab30c 100644 --- a/sys/arch/kbus/kbus/locore.s +++ b/sys/arch/kbus/kbus/locore.s @@ -3087,8 +3087,6 @@ ENTRY(write_user_windows) */ ENTRY(switchexit) mov %o0, %g2 ! save the - mov %o1, %g3 ! ... three parameters - mov %o2, %g4 ! ... to kmem_free /* * Change pcb to idle u. area, i.e., set %sp to top of stack @@ -3119,10 +3117,8 @@ ENTRY(switchexit) SET_SP_REDZONE(%l6, %l5) #endif wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps - mov %g2, %o0 ! now ready to call kmem_free - mov %g3, %o1 - call _kmem_free - mov %g4, %o2 + call _exit2 + mov %g2, %o0 /* * Now fall through to `the last switch'. %g6 was set to diff --git a/sys/arch/kbus/kbus/vm_machdep.c b/sys/arch/kbus/kbus/vm_machdep.c index 7c054c2029f..c80e06aa8d2 100644 --- a/sys/arch/kbus/kbus/vm_machdep.c +++ b/sys/arch/kbus/kbus/vm_machdep.c @@ -437,8 +437,8 @@ cpu_exit(p) } free((void *)fs, M_SUBPROC); } - vmspace_free(p->p_vmspace); - switchexit(kernel_map, p->p_addr, USPACE); + + switchexit(p); /* NOTREACHED */ } diff --git a/sys/arch/mac68k/mac68k/locore.s b/sys/arch/mac68k/mac68k/locore.s index efe1f0d149a..7e062a830b4 100644 --- a/sys/arch/mac68k/mac68k/locore.s +++ b/sys/arch/mac68k/mac68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.22 1999/01/20 13:31:16 niklas Exp $ */ +/* $OpenBSD: locore.s,v 1.23 2000/06/05 11:02:59 art Exp $ */ /* $NetBSD: locore.s,v 1.74 1997/02/02 08:17:46 thorpej Exp $ */ /* @@ -1232,12 +1232,10 @@ ENTRY(switch_exit) movl #nullpcb,_curpcb | save state into garbage pcb lea tmpstk,sp | goto a tmp stack - /* Free old process's user area. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address of process's u-area - movl _kernel_map,sp@- | map it was allocated in - jbsr _kmem_free | deallocate it - lea sp@(12),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args jra _cpu_switch diff --git a/sys/arch/mac68k/mac68k/vm_machdep.c b/sys/arch/mac68k/mac68k/vm_machdep.c index 82e722ca7c5..e89a7fe0a9a 100644 --- a/sys/arch/mac68k/mac68k/vm_machdep.c +++ b/sys/arch/mac68k/mac68k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.15 1999/10/10 18:29:22 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.16 2000/06/05 11:03:00 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.21 1996/09/16 18:00:31 scottr Exp $ */ /* @@ -153,7 +153,6 @@ volatile void cpu_exit(p) struct proc *p; { - vmspace_free(p->p_vmspace); (void) splhigh(); cnt.v_swtch++; diff --git a/sys/arch/mips/mips/vm_machdep.c b/sys/arch/mips/mips/vm_machdep.c index 72c64feb844..281e0974a0d 100644 --- a/sys/arch/mips/mips/vm_machdep.c +++ b/sys/arch/mips/mips/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.7 1999/09/03 18:01:18 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.8 2000/06/05 11:03:00 art Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -182,10 +182,8 @@ cpu_exit(p) if (machFPCurProcPtr == p) machFPCurProcPtr = (struct proc *)0; - vmspace_free(p->p_vmspace); - (void) splhigh(); - kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES)); + exit2(p); /* XXX - probably very wrong */ switch_exit(); /* NOTREACHED */ } diff --git a/sys/arch/mvme68k/mvme68k/locore.s b/sys/arch/mvme68k/mvme68k/locore.s index 9ec195e0c03..1cce4c1d1ea 100644 --- a/sys/arch/mvme68k/mvme68k/locore.s +++ b/sys/arch/mvme68k/mvme68k/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.20 2000/01/06 03:21:43 smurph Exp $ */ +/* $OpenBSD: locore.s,v 1.21 2000/06/05 11:03:01 art Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -1316,12 +1316,10 @@ ENTRY(switch_exit) movl #nullpcb,_curpcb | save state into garbage pcb lea tmpstk,sp | goto a tmp stack - /* Free old process's resources. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address of process's u-area - movl _kernel_map,sp@- | map it was allocated in - jbsr _kmem_free | deallocate it - lea sp@(12),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args jra _cpu_switch diff --git a/sys/arch/mvme68k/mvme68k/vm_machdep.c b/sys/arch/mvme68k/mvme68k/vm_machdep.c index 1722b359ce4..1182ded6de2 100644 --- a/sys/arch/mvme68k/mvme68k/vm_machdep.c +++ b/sys/arch/mvme68k/mvme68k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.14 1999/09/27 20:30:32 smurph Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.15 2000/06/05 11:03:02 art Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -130,8 +130,6 @@ cpu_exit(p) struct proc *p; { - vmspace_free(p->p_vmspace); - (void) splimp(); cnt.v_swtch++; switch_exit(p); diff --git a/sys/arch/mvme88k/mvme88k/vm_machdep.c b/sys/arch/mvme88k/mvme88k/vm_machdep.c index c3b3d79cef1..35cc2e080ef 100644 --- a/sys/arch/mvme88k/mvme88k/vm_machdep.c +++ b/sys/arch/mvme88k/mvme88k/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.11 1999/09/27 19:13:24 smurph Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.12 2000/06/05 11:03:02 art Exp $ */ /* * Copyright (c) 1998 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -42,7 +42,7 @@ * from: Utah $Hdr: vm_machdep.c 1.21 91/04/06$ * from: @(#)vm_machdep.c 7.10 (Berkeley) 5/7/91 * vm_machdep.c,v 1.3 1993/07/07 07:09:32 cgd Exp - * $Id: vm_machdep.c,v 1.11 1999/09/27 19:13:24 smurph Exp $ + * $Id: vm_machdep.c,v 1.12 2000/06/05 11:03:02 art Exp $ */ #include <sys/param.h> @@ -175,10 +175,9 @@ void cpu_exit(struct proc *p) { extern volatile void switch_exit(); - vmspace_free(p->p_vmspace); (void) splimp(); - kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES)); + exit2(p); /* XXX - can't be right! */ switch_exit(p); /* NOTREACHED */ } diff --git a/sys/arch/pmax/pmax/vm_machdep.c b/sys/arch/pmax/pmax/vm_machdep.c index f6d106324b0..3f376e84eba 100644 --- a/sys/arch/pmax/pmax/vm_machdep.c +++ b/sys/arch/pmax/pmax/vm_machdep.c @@ -186,10 +186,8 @@ void cpu_exit(p) if (machFPCurProcPtr == p) machFPCurProcPtr = (struct proc *)0; - vmspace_free(p->p_vmspace); - (void) splhigh(); - kmem_free(kernel_map, (vm_offset_t)p->p_addr, ctob(UPAGES)); + exit2(p); /* XXX - probably very wrong. */ switch_exit(); /* NOTREACHED */ } diff --git a/sys/arch/powerpc/powerpc/locore.S b/sys/arch/powerpc/powerpc/locore.S index 9283eeea4e9..2ee811ca8c9 100644 --- a/sys/arch/powerpc/powerpc/locore.S +++ b/sys/arch/powerpc/powerpc/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.10 2000/03/31 04:11:02 rahnds Exp $ */ +/* $OpenBSD: locore.S,v 1.11 2000/06/05 11:03:03 art Exp $ */ /* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */ /* @@ -194,12 +194,12 @@ _ENTRY(_C_LABEL(switchexit)) lis 7,_C_LABEL(curpcb)@ha stw 6,_C_LABEL(curpcb)@l(7) addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */ -/* Now free the old user structure (args are already in r3, r4, r5) */ -#ifdef UVM - bl _C_LABEL(uvm_km_free) -#else - bl _C_LABEL(kmem_free) -#endif + /* + * Schedule the vmspace and stack to be freed (the proc arg is + * already in r3). + */ + bl _C_LABEL(exit2) + /* Fall through to cpu_switch to actually select another proc */ /* diff --git a/sys/arch/powerpc/powerpc/vm_machdep.c b/sys/arch/powerpc/powerpc/vm_machdep.c index 88133ac3ef0..df840c21577 100644 --- a/sys/arch/powerpc/powerpc/vm_machdep.c +++ b/sys/arch/powerpc/powerpc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.11 2000/01/16 22:52:22 rahnds Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.12 2000/06/05 11:03:04 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.1 1996/09/30 16:34:57 ws Exp $ */ /* @@ -180,13 +180,8 @@ cpu_exit(p) if (p == fpuproc) /* release the fpu */ fpuproc = 0; -#ifdef UVM - uvmspace_free(p->p_vmspace); -#else - vmspace_free(p->p_vmspace); -#endif (void)splhigh(); - switchexit(kernel_map, p->p_addr, USPACE); + switchexit(p); } /* diff --git a/sys/arch/sparc/include/cpu.h b/sys/arch/sparc/include/cpu.h index c510fb680d1..b0268a2c0ce 100644 --- a/sys/arch/sparc/include/cpu.h +++ b/sys/arch/sparc/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.9 2000/05/18 13:31:12 jason Exp $ */ +/* $OpenBSD: cpu.h,v 1.10 2000/06/05 11:02:52 art Exp $ */ /* $NetBSD: cpu.h,v 1.24 1997/03/15 22:25:15 pk Exp $ */ /* @@ -75,7 +75,7 @@ */ #define cpu_swapin(p) /* nothing */ #define cpu_swapout(p) /* nothing */ -#define cpu_wait(p) /* nothing */ +#define cpu_wait(p) /* nothing */ /* * Arguments to hardclock, softclock and gatherstats encapsulate the diff --git a/sys/arch/sparc/include/pmap.h b/sys/arch/sparc/include/pmap.h index 12cc90be105..ef9f26ee2cb 100644 --- a/sys/arch/sparc/include/pmap.h +++ b/sys/arch/sparc/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.15 1999/12/09 21:35:28 art Exp $ */ +/* $OpenBSD: pmap.h,v 1.16 2000/06/05 11:02:52 art Exp $ */ /* $NetBSD: pmap.h,v 1.30 1997/08/04 20:00:47 pk Exp $ */ /* @@ -310,7 +310,7 @@ void kvm_setcache __P((caddr_t, int, int)); #define kvm_recache(addr, npages) kvm_setcache(addr, npages, 1) void pmap_cache_enable __P((void)); struct user; -void switchexit __P((vm_map_t, struct user *, int)); +void switchexit __P((struct proc *)); int mmu_pagein __P((struct pmap *pm, vaddr_t, int)); void pmap_writetext __P((unsigned char *, int)); diff --git a/sys/arch/sparc/sparc/locore.s b/sys/arch/sparc/sparc/locore.s index f9f38a40298..49ca3f92005 100644 --- a/sys/arch/sparc/sparc/locore.s +++ b/sys/arch/sparc/sparc/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.37 2000/02/27 05:25:01 deraadt Exp $ */ +/* $OpenBSD: locore.s,v 1.38 2000/06/05 11:02:53 art Exp $ */ /* $NetBSD: locore.s,v 1.73 1997/09/13 20:36:48 pk Exp $ */ /* @@ -4317,9 +4317,7 @@ ENTRY(write_user_windows) * and note that the `last loaded process' is nonexistent. */ ENTRY(switchexit) - mov %o0, %g2 ! save the - mov %o1, %g3 ! ... three parameters - mov %o2, %g4 ! ... to kmem_free + mov %o0, %g2 ! save proc for exit2() call /* * Change pcb to idle u. area, i.e., set %sp to top of stack @@ -4341,14 +4339,8 @@ ENTRY(switchexit) SET_SP_REDZONE(%l6, %l5) #endif wr %g0, PSR_S|PSR_ET, %psr ! and then enable traps - mov %g2, %o0 ! now ready to call kmem_free - mov %g3, %o1 -#if defined(UVM) - call _uvm_km_free -#else - call _kmem_free -#endif - mov %g4, %o2 + call _exit2 ! exit2(p) + mov %g2, %o0 /* * Now fall through to `the last switch'. %g6 was set to diff --git a/sys/arch/sparc/sparc/vm_machdep.c b/sys/arch/sparc/sparc/vm_machdep.c index 5e3f1ddf892..4e311ed46ea 100644 --- a/sys/arch/sparc/sparc/vm_machdep.c +++ b/sys/arch/sparc/sparc/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.19 2000/05/01 18:28:58 art Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.20 2000/06/05 11:02:53 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.30 1997/03/10 23:55:40 pk Exp $ */ /* @@ -521,10 +521,11 @@ cpu_set_kpc(p, pc, arg) /* * cpu_exit is called as the last action during exit. - * We release the address space and machine-dependent resources, - * including the memory for the user structure and kernel stack. - * Since the latter is also the interrupt stack, we release it - * from assembly code after switching to a temporary pcb+stack. + * + * We clean up a little and then call switchexit() with the old proc + * as an argument. switchexit() switches to the idle context, schedules + * the old vmspace and stack to be freed, then selects a new process to + * run. */ void cpu_exit(p) @@ -539,12 +540,8 @@ cpu_exit(p) } free((void *)fs, M_SUBPROC); } -#if defined(UVM) - uvmspace_free(p->p_vmspace); -#else - vmspace_free(p->p_vmspace); -#endif - switchexit(kernel_map, p->p_addr, USPACE); + + switchexit(p); /* NOTREACHED */ } diff --git a/sys/arch/sun3/sun3/locore.s b/sys/arch/sun3/sun3/locore.s index cc72f3f04fe..13ae9b105e4 100644 --- a/sys/arch/sun3/sun3/locore.s +++ b/sys/arch/sun3/sun3/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.18 1997/04/05 20:22:01 kstailey Exp $ */ +/* $OpenBSD: locore.s,v 1.19 2000/06/05 11:03:04 art Exp $ */ /* $NetBSD: locore.s,v 1.40 1996/11/06 20:19:54 cgd Exp $ */ /* @@ -935,12 +935,10 @@ ENTRY(switch_exit) lea tmpstk,sp | goto a tmp stack movl a0,sp@- | pass proc ptr down - /* Free old process's u-area. */ - movl #USPACE,sp@- | size of u-area - movl a0@(P_ADDR),sp@- | address of process's u-area - movl _kernel_map,sp@- | map it was allocated in - jbsr _kmem_free | deallocate it - lea sp@(12),sp | pop args + /* Schedule the vmspace and stack to be freed. */ + movl a0,sp@- | exit2(p) + jbsr _C_LABEL(exit2) + lea sp@(4),sp | pop args jra _cpu_switch diff --git a/sys/arch/sun3/sun3/vm_machdep.c b/sys/arch/sun3/sun3/vm_machdep.c index cff257308c3..280dcea9a76 100644 --- a/sys/arch/sun3/sun3/vm_machdep.c +++ b/sys/arch/sun3/sun3/vm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vm_machdep.c,v 1.11 2000/03/02 23:02:15 todd Exp $ */ +/* $OpenBSD: vm_machdep.c,v 1.12 2000/06/05 11:03:04 art Exp $ */ /* $NetBSD: vm_machdep.c,v 1.35 1996/04/26 18:38:06 gwr Exp $ */ /* @@ -198,8 +198,6 @@ cpu_exit(p) struct proc *p; { - vmspace_free(p->p_vmspace); - (void) splimp(); cnt.v_swtch++; switch_exit(p); diff --git a/sys/arch/vax/vax/subr.s b/sys/arch/vax/vax/subr.s index 53cbee8332f..ec82a52c642 100644 --- a/sys/arch/vax/vax/subr.s +++ b/sys/arch/vax/vax/subr.s @@ -1,4 +1,4 @@ -/* $OpenBSD: subr.s,v 1.7 2000/04/27 01:10:13 bjc Exp $ */ +/* $OpenBSD: subr.s,v 1.8 2000/06/05 11:03:05 art Exp $ */ /* $NetBSD: subr.s,v 1.32 1999/03/25 00:41:48 mrg Exp $ */ /* @@ -301,8 +301,8 @@ ENTRY(cpu_exit,0) mtpr $0x18,$PR_IPL # Block almost everything addl3 $512,_scratch,sp # Change stack, and schedule it to be freed - pushl P_VMSPACE(r6) - calls $1,_uvmspace_free + pushl r6 + calls $1,_exit2 clrl r0 # No process to switch from bicl3 $0xc0000000,_scratch,r1 diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 13ba4c4f93d..105ad19f43f 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.52 2000/03/23 16:54:44 art Exp $ */ +/* $OpenBSD: init_main.c,v 1.53 2000/06/05 11:02:50 art Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -140,6 +140,7 @@ void check_console __P((struct proc *)); void start_init __P((void *)); void start_pagedaemon __P((void *)); void start_update __P((void *)); +void start_reaper __P((void *)); #ifdef cpu_set_init_frame void *initframep; /* XXX should go away */ @@ -433,7 +434,11 @@ main(framep) if (kthread_create(start_pagedaemon, NULL, NULL, "pagedaemon")) panic("fork pagedaemon"); - /* Create process 3, the update daemon kernel thread. */ + /* Create process 3, the reaper daemon kernel thread. */ + if (kthread_create(start_reaper, NULL, NULL, "reaper")) + panic("fork reaper"); + + /* Create process 4, the update daemon kernel thread. */ if (kthread_create(start_update, NULL, NULL, "update")) { #ifdef DIAGNOSTIC panic("fork update"); @@ -657,3 +662,11 @@ start_update(arg) sched_sync(curproc); /* NOTREACHED */ } + +void +start_reaper(arg) + void *arg; +{ + reaper(); + /* NOTREACHED */ +} diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a854b511733..bed30ca982f 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.24 2000/05/05 08:38:23 art Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.25 2000/06/05 11:02:50 art Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -213,15 +213,24 @@ exit1(p, rv) ktrsettracevnode(p, NULL); #endif /* - * Remove proc from allproc queue and pidhash chain. - * Place onto zombproc. Unlink from parent's child list. + * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP! */ + p->p_stat = SDEAD; + + /* + * Remove proc from pidhash chain so looking it up won't + * work. Move it from allproc to zombproc, but do not yet + * wake up the reaper. We will put the proc on the + * deadproc list later (using the p_hash member), and + * wake up the reaper when we do. + */ + LIST_REMOVE(p, p_hash); LIST_REMOVE(p, p_list); LIST_INSERT_HEAD(&zombproc, p, p_list); - p->p_stat = SZOMB; - - LIST_REMOVE(p, p_hash); + /* + * Give orphaned children to init(8). + */ q = p->p_children.lh_first; if (q) /* only need this if any child is S_ZOMB */ wakeup((caddr_t)initproc); @@ -268,18 +277,13 @@ exit1(p, rv) if (pp->p_children.lh_first == NULL) wakeup((caddr_t)pp); } - psignal(p->p_pptr, SIGCHLD); - wakeup((caddr_t)p->p_pptr); /* * Notify procfs debugger */ if (p->p_flag & P_FSTRACE) wakeup((caddr_t)p); -#if defined(tahoe) - /* move this to cpu_exit */ - p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL; -#endif + /* * Clear curproc after we've done all operations * that could block, and before tearing down the rest @@ -295,17 +299,94 @@ exit1(p, rv) p->p_limit = NULL; /* - * Finally, call machine-dependent code to release the remaining - * resources including address space, the kernel stack and pcb. - * The address space is released by "vmspace_free(p->p_vmspace)"; - * This is machine-dependent, as we may have to change stacks - * or ensure that the current one isn't reallocated before we - * finish. cpu_exit will end with a call to cpu_swtch(), finishing - * our execution (pun intended). + * Finally, call machine-dependent code to switch to a new + * context (possibly the idle context). Once we are no longer + * using the dead process's vmspace and stack, exit2() will be + * called to schedule those resources to be released by the + * reaper thread. + * + * Note that cpu_exit() will end with a call equivalent to + * cpu_switch(), finishing our execution (pun intended). */ cpu_exit(p); } +/* + * We are called from cpu_exit() once it is safe to schedule the + * dead process's resources to be freed. + * + * NOTE: One must be careful with locking in this routine. It's + * called from a critical section in machine-dependent code, so + * we should refrain from changing any interrupt state. + * + * We lock the deadproc list (a spin lock), place the proc on that + * list (using the p_hash member), and wake up the reaper. + */ +void +exit2(p) + struct proc *p; +{ + + simple_lock(&deadproc_slock); + LIST_INSERT_HEAD(&deadproc, p, p_hash); + simple_unlock(&deadproc_slock); + + wakeup(&deadproc); +} + +/* + * Process reaper. This is run by a kernel thread to free the resources + * of a dead process. Once the resources are free, the process becomes + * a zombie, and the parent is allowed to read the undead's status. + */ +void +reaper() +{ + struct proc *p; + + for (;;) { + simple_lock(&deadproc_slock); + p = LIST_FIRST(&deadproc); + if (p == NULL) { + /* No work for us; go to sleep until someone exits. */ + simple_unlock(&deadproc_slock); + (void) tsleep(&deadproc, PVM, "reaper", 0); + continue; + } + + /* Remove us from the deadproc list. */ + LIST_REMOVE(p, p_hash); + simple_unlock(&deadproc_slock); + + /* + * Give machine-dependent code a chance to free any + * resources it couldn't free while still running on + * that process's context. This must be done before + * uvm_exit(), in case these resources are in the PCB. + */ + cpu_wait(p); + +#ifdef UVM + /* + * Free the VM resources we're still holding on to. + * We must do this from a valid thread because doing + * so may block. + */ + uvm_exit(p); +#else + vmspace_free(p->p_vmspace); + kmem_free(kernel_map, (vaddr_t)p->p_addr, USPACE); +#endif + + /* Process is now a true zombie. */ + p->p_stat = SZOMB; + + /* Wake up the parent so it can get exit status. */ + psignal(p->p_pptr, SIGCHLD); + wakeup((caddr_t)p->p_pptr); + } +} + int sys_wait4(q, v, retval) register struct proc *q; @@ -354,7 +435,7 @@ loop: if (SCARG(uap, rusage) && (error = copyout((caddr_t)p->p_ru, (caddr_t)SCARG(uap, rusage), - sizeof (struct rusage)))) + sizeof(struct rusage)))) return (error); /* * If we got the child via a ptrace 'attach', @@ -400,12 +481,6 @@ loop: if (p->p_textvp) vrele(p->p_textvp); - /* - * Give machine-dependent layer a chance - * to free anything that cpu_exit couldn't - * release while still running in process context. - */ - cpu_wait(p); FREE(p, M_PROC); nprocs--; return (0); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index d431cc3315b..b8bfac34f4d 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_proc.c,v 1.6 1999/04/28 09:28:14 art Exp $ */ +/* $OpenBSD: kern_proc.c,v 1.7 2000/06/05 11:02:50 art Exp $ */ /* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */ /* @@ -75,6 +75,16 @@ u_long pgrphash; struct proclist allproc; struct proclist zombproc; +/* + * Locking of this proclist is special; it's accessed in a + * critical section of process exit, and thus locking it can't + * modify interrupt state. We use a simple spin lock for this + * proclist. Processes on this proclist are also on zombproc; + * we use the p_hash member to linkup to deadproc. + */ +struct simplelock deadproc_slock; +struct proclist deadproc; /* dead, but not yet undead */ + static void orphanpg __P((struct pgrp *)); #ifdef DEBUG void pgrpdump __P((void)); @@ -89,6 +99,10 @@ procinit() LIST_INIT(&allproc); LIST_INIT(&zombproc); + + LIST_INIT(&deadproc); + simple_lock_init(&deadproc_slock); + pidhashtbl = hashinit(maxproc / 4, M_PROC, M_WAITOK, &pidhash); pgrphashtbl = hashinit(maxproc / 4, M_PROC, M_WAITOK, &pgrphash); uihashtbl = hashinit(maxproc / 16, M_PROC, M_WAITOK, &uihash); @@ -325,7 +339,7 @@ fixjobc(p, pgrp, entering) for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) if ((hispgrp = p->p_pgrp) != pgrp && hispgrp->pg_session == mysession && - p->p_stat != SZOMB) { + P_ZOMBIE(p) == 0) { if (entering) hispgrp->pg_jobc++; else if (--hispgrp->pg_jobc == 0) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index de148e69821..caadb6620fa 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.37 2000/04/21 15:47:27 millert Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.38 2000/06/05 11:02:50 art Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -542,7 +542,7 @@ killpg1(cp, signum, pgid, all) !cansignal(cp, pc, p, signum)) continue; nfound++; - if (signum) + if (signum && P_ZOMBIE(p) == 0) psignal(p, signum); } } diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 59b50786171..7ca4b4fc1ce 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.24 2000/04/19 09:58:20 art Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.25 2000/06/05 11:02:51 art Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -754,6 +754,7 @@ setrunnable(p) case 0: case SRUN: case SZOMB: + case SDEAD: default: panic("setrunnable"); case SSTOP: diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 5db51a627e7..eca6d0e08da 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.34 2000/05/06 17:08:14 deraadt Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.35 2000/06/05 11:02:51 art Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -806,7 +806,7 @@ fill_eproc(p, ep) ep->e_sess = p->p_pgrp->pg_session; ep->e_pcred = *p->p_cred; ep->e_ucred = *p->p_ucred; - if (p->p_stat == SIDL || p->p_stat == SZOMB) { + if (p->p_stat == SIDL || P_ZOMBIE(p)) { ep->e_vm.vm_rssize = 0; ep->e_vm.vm_tsize = 0; ep->e_vm.vm_dsize = 0; diff --git a/sys/kern/tty.c b/sys/kern/tty.c index e43024e9108..fa632857111 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.39 2000/03/23 17:20:23 art Exp $ */ +/* $OpenBSD: tty.c,v 1.40 2000/06/05 11:02:51 art Exp $ */ /* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */ /*- @@ -2034,7 +2034,7 @@ ttyinfo(tp) tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT; ttyprintf(tp, "%d%% %ldk\n", tmp / 100, - pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 : + pick->p_stat == SIDL || P_ZOMBIE(pick) ? 0 : vm_resident_count(pick->p_vmspace)); } tp->t_rocount = 0; /* so pending input will be retyped if BS */ @@ -2087,7 +2087,7 @@ proc_compare(p1, p2) /* * weed out zombies */ - switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) { + switch (TESTAB(P_ZOMBIE(p1), P_ZOMBIE(p2))) { case ONLYA: return (1); case ONLYB: diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 9ddd84f1a93..5ed87c3de54 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.30 2000/04/19 09:58:19 art Exp $ */ +/* $OpenBSD: proc.h,v 1.31 2000/06/05 11:02:48 art Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -214,6 +214,9 @@ struct proc { #define SSLEEP 3 /* Sleeping on an address. */ #define SSTOP 4 /* Process debugging or suspension. */ #define SZOMB 5 /* Awaiting collection by parent. */ +#define SDEAD 6 /* Process is almost a zombie. */ + +#define P_ZOMBIE(p) ((p)->p_stat == SZOMB || (p)->p_stat == SDEAD) /* These flags are kept in p_flag. */ #define P_ADVLOCK 0x000001 /* Proc may hold a POSIX adv. lock. */ @@ -325,6 +328,10 @@ extern int randompid; /* fork() should create random pid's */ LIST_HEAD(proclist, proc); extern struct proclist allproc; /* List of all processes. */ extern struct proclist zombproc; /* List of zombie processes. */ + +extern struct proclist deadproc; /* List of dead processes. */ +extern struct simplelock deadproc_slock; + struct proc *initproc; /* Process slots for init, pager. */ #define NQS 32 /* 32 run queues. */ @@ -360,7 +367,9 @@ void swapin __P((struct proc *)); int tsleep __P((void *chan, int pri, char *wmesg, int timo)); void unsleep __P((struct proc *)); void wakeup __P((void *chan)); +void reaper __P((void)); void exit1 __P((struct proc *, int)); +void exit2 __P((struct proc *)); int fork1 __P((struct proc *, int, void *, size_t, register_t *)); void kmeminit __P((void)); void rqinit __P((void)); |