Rearrange process exit path to avoid need to free resources from different

process context ('reaper').

From within the exiting process context:
* deactivate pmap and free vmspace while we can still block
* introduce MD cpu_lwp_free() - this cleans all MD-specific context (such
  as FPU state), and is the last potentially blocking operation;
  all of cpu_wait(), and most of cpu_exit(), is now folded into cpu_lwp_free()
* process is now immediatelly marked as zombie and made available for pickup
  by parent; the remaining last lwp continues the exit as fully detached
* MI (rather than MD) code bumps uvmexp.swtch, cpu_exit() is now same
  for both 'process' and 'lwp' exit

uvm_lwp_exit() is modified to never block; the u-area memory is now
always just linked to the list of available u-areas. Introduce (blocking)
uvm_uarea_drain(), which is called to release the excessive u-area memory;
this is called by parent within wait4(), or by pagedaemon on memory shortage.
uvm_uarea_free() is now private function within uvm_glue.c.

MD process/lwp exit code now always calls lwp_exit2() immediatelly after
switching away from the exiting lwp.

g/c now unneeded routines and variables, including the reaper kernel thread
This commit is contained in:
jdolecek 2004-01-04 11:33:29 +00:00
parent 3c5939dc02
commit 089abdad44
50 changed files with 401 additions and 478 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.6 2003/07/14 22:48:20 lukem Exp $ */
/* $NetBSD: vm_machdep.c,v 1.7 2004/01/04 11:33:29 jdolecek Exp $ */
/*-
* Copyright (c) 2000, 2001 Ben Harris
@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.6 2003/07/14 22:48:20 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.7 2004/01/04 11:33:29 jdolecek Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -159,17 +159,19 @@ cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
}
void
cpu_exit(struct lwp *l, int proc)
cpu_lwp_free(struct lwp *l, int proc)
{
/* Nothing to do here? */
}
void
cpu_exit(struct lwp *l)
{
int s;
/* Nothing to do here? */
/* I think this is safe on a uniprocessor machine */
if (proc)
exit2(l);
else
lwp_exit2(l);
lwp_exit2(l);
SCHED_LOCK(s); /* expected by cpu_switch */
cpu_switch(l, NULL);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.80 2003/06/29 22:28:04 fvdl Exp $ */
/* $NetBSD: vm_machdep.c,v 1.81 2004/01/04 11:33:29 jdolecek Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@ -29,7 +29,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.80 2003/06/29 22:28:04 fvdl Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.81 2004/01/04 11:33:29 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -94,6 +94,15 @@ cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
return error;
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_proc(l, 0);
}
/*
* cpu_exit is called as the last action during exit.
* We block interrupts and call switch_exit. switch_exit switches
@ -101,21 +110,9 @@ cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
* as if it were switching from proc0.
*/
void
cpu_exit(struct lwp *l, int proc)
{
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_proc(l, 0);
/*
* Deactivate the exiting address space before the vmspace
* is freed. Note that we will continue to run on this
* vmspace's context until the switch to proc0 in switch_exit().
*/
pmap_deactivate(l);
cpu_exit(struct lwp *l)
(void) splhigh();
switch_exit(l, proc ? exit2 : lwp_exit2);
switch_exit(l, lwp_exit2);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.61 2003/08/07 16:26:33 agc Exp $ */
/* $NetBSD: cpu.h,v 1.62 2004/01/04 11:33:29 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -216,7 +216,6 @@ void cpu_pause_resume_all(int);
* definitions of cpu-dependent requirements
* referenced in generic code
*/
#define cpu_wait(p) /* nothing */
#define cpu_number() alpha_pal_whami()
#define cpu_proc_fork(p1, p2) /* nothing */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.3 2003/08/07 16:26:35 agc Exp $ */
/* $NetBSD: vm_machdep.c,v 1.4 2004/01/04 11:33:29 jdolecek Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.3 2003/08/07 16:26:35 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.4 2004/01/04 11:33:29 jdolecek Exp $");
#include "opt_user_ldt.h"
#include "opt_largepages.h"
@ -244,6 +244,17 @@ cpu_swapout(l)
fpusave_lwp(l, 1);
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
/* If we were using the FPU, forget about it. */
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_lwp(l, 0);
if (proc && l->l_md.md_flags & MDP_USEDMTRR)
mtrr_clean(l->l_proc);
}
/*
* cpu_exit is called as the last action during exit.
*
@ -252,25 +263,10 @@ cpu_swapout(l)
* jumps into switch() to wait for another process to wake up.
*/
void
cpu_exit(struct lwp *l, int proc)
cpu_exit(struct lwp *l)
{
/* If we were using the FPU, forget about it. */
if (l->l_addr->u_pcb.pcb_fpcpu != NULL)
fpusave_lwp(l, 0);
if (proc && l->l_md.md_flags & MDP_USEDMTRR)
mtrr_clean(l->l_proc);
/*
* No need to do user LDT cleanup here; it's handled in
* pmap_destroy().
*/
pmap_deactivate(l);
uvmexp.swtch++;
switch_exit(l, proc ? exit2 : lwp_exit2);
switch_exit(l, lwp_exit2);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.56 2003/08/07 16:26:45 agc Exp $ */
/* $NetBSD: cpu.h,v 1.57 2004/01/04 11:33:29 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -111,7 +111,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.10 2003/11/02 16:37:09 jdolecek Exp $ */
/* $NetBSD: cpu.h,v 1.11 2004/01/04 11:33:29 jdolecek Exp $ */
/*
* Copyright (C) 1995-1997 Wolfgang Solfrank.
@ -61,7 +61,6 @@ void physaccess __P((caddr_t, caddr_t, int, int));
#define PROC_PC(p) (trapframe(p)->srr0)
#define cpu_swapout(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_number() 0
extern void delay __P((unsigned));

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.30 2003/10/23 08:59:10 scw Exp $ */
/* $NetBSD: vm_machdep.c,v 1.31 2004/01/04 11:33:29 jdolecek Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.30 2003/10/23 08:59:10 scw Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.31 2004/01/04 11:33:29 jdolecek Exp $");
#include "opt_armfpe.h"
#include "opt_pmap_debug.h"
@ -225,7 +225,7 @@ cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
*/
void
cpu_exit(struct lwp *l, int proc)
cpu_lwp_free(struct lwp *l, int proc)
{
#ifdef ARMFPE
/* Abort any active FP operation and deactivate the context */
@ -249,10 +249,13 @@ cpu_exit(struct lwp *l, int proc)
log(LOG_INFO, "%d bytes of svc stack fill pattern\n", loop);
}
#endif /* STACKCHECKS */
uvmexp.swtch++;
switch_exit(l, &lwp0, proc ? exit2 : lwp_exit2);
}
void
cpu_exit(struct lwp *l)
{
switch_exit(l, &lwp0, lwp_exit2);
}
void
cpu_swapin(l)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */
/* $NetBSD: cpu.h,v 1.35 2004/01/04 11:33:29 jdolecek Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -240,8 +240,6 @@ extern int astpending;
#define signotify(p) setsoftast()
#define cpu_wait(p) /* nothing */
/*
* Preempt the current process if in interrupt from user mode,
* or after the current trap/syscall if in system mode.

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.42 2003/08/07 16:27:03 agc Exp $ */
/* $NetBSD: cpu.h,v 1.43 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -112,7 +112,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.7 2003/08/07 16:27:15 agc Exp $ */
/* $NetBSD: cpu.h,v 1.8 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -107,7 +107,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.42 2003/08/07 16:27:39 agc Exp $ */
/* $NetBSD: cpu.h,v 1.43 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -117,7 +117,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.9 2003/11/08 15:19:20 tsutsui Exp $ */
/* $NetBSD: cpu.h,v 1.10 2004/01/04 11:33:30 jdolecek Exp $ */
/* $OpenBSD: cpu.h,v 1.20 2001/01/29 00:01:58 mickey Exp $ */
@ -186,7 +186,6 @@ extern struct cpu_info cpu_info_store;
* definitions of cpu-dependent requirements
* referenced in generic code
*/
#define cpu_wait(p) /* nothing */
#define cpu_number() 0
#define cpu_proc_fork(p1, p2)

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.8 2003/11/28 19:02:25 chs Exp $ */
/* $NetBSD: vm_machdep.c,v 1.9 2004/01/04 11:33:30 jdolecek Exp $ */
/* $OpenBSD: vm_machdep.c,v 1.25 2001/09/19 20:50:56 mickey Exp $ */
@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.8 2003/11/28 19:02:25 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.9 2004/01/04 11:33:30 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -227,14 +227,18 @@ cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
}
void
cpu_exit(struct lwp *l, int proc)
cpu_lwp_free(struct lwp *l, int proc)
{
(void) splsched();
uvmexp.swtch++;
/* Flush the LWP out of the FPU. */
hppa_fpu_flush(l);
switch_exit(l, proc ? exit2 : lwp_exit2);
}
void
cpu_exit(struct lwp *l)
{
(void) splsched();
switch_exit(l, lwp_exit2);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.112 2003/10/27 14:11:47 junyoung Exp $ */
/* $NetBSD: vm_machdep.c,v 1.113 2004/01/04 11:33:30 jdolecek Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.112 2003/10/27 14:11:47 junyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.113 2004/01/04 11:33:30 jdolecek Exp $");
#include "opt_user_ldt.h"
#include "opt_largepages.h"
@ -248,19 +248,21 @@ cpu_swapout(l)
#endif
}
void
cpu_exit(struct lwp *l)
{
switch_exit(l, lwp_exit2);
/* NOTREACHED */
}
/*
* cpu_exit is called as the last action during exit.
*
* We clean up a little and then call switch_exit() with the old proc as an
* argument. switch_exit() first switches to proc0's context, and finally
* jumps into switch() to wait for another process to wake up.
*
* If proc==0, we're an exiting lwp, and call switch_lwp_exit() instead of
* switch_exit(), and only do LWP-appropriate cleanup (e.g. don't deactivate
* the pmap).
* cpu_lwp_free is called from exit() to let machine-dependent
* code free machine-dependent resources that should be cleaned
* while we can still block and have process associated with us
*/
void
cpu_exit(struct lwp *l, int proc)
cpu_lwp_free(struct lwp *l, int proc)
{
#if NNPX > 0
@ -274,35 +276,11 @@ cpu_exit(struct lwp *l, int proc)
mtrr_clean(l->l_proc);
#endif
/*
* No need to do user LDT cleanup here; it's handled in
* pmap_destroy().
*/
/*
* Deactivate the address space before the vmspace is
* freed. Note that we will continue to run on this
* vmspace's context until the switch to the idle process
* in switch_exit().
*/
pmap_deactivate(l);
uvmexp.swtch++;
switch_exit(l, proc ? exit2 : lwp_exit2);
}
/*
* cpu_wait is called from reaper() to let machine-dependent
* code free machine-dependent resources that couldn't be freed
* in cpu_exit().
*/
void
cpu_wait(l)
struct lwp *l;
{
/* Nuke the TSS. */
tss_free(l->l_md.md_tss_sel);
#ifdef DEBUG
l->l_md.md_tss_sel = 0xfeedbeed;
#endif
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.7 2003/08/07 16:28:05 agc Exp $ */
/* $NetBSD: cpu.h,v 1.8 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -108,7 +108,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: switch_subr.s,v 1.8 2003/11/04 10:33:16 dsl Exp $ */
/* $NetBSD: switch_subr.s,v 1.9 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -111,33 +111,6 @@ GLOBAL(masterpaddr) | XXXcompatibility (debuggers)
ASBSS(nullpcb,SIZEOF_PCB)
/*
* void switch_exit(struct lwp *);
*
* At exit of a process, do a switch for the last time.
* Switch to a safe stack and PCB, and select a new process to run. The
* old stack and u-area will be freed by the reaper.
*
* MUST BE CALLED AT SPLHIGH!
*/
ENTRY(switch_exit)
movl %sp@(4),%a0
/* save state into garbage pcb */
movl #_ASM_LABEL(nullpcb),_C_LABEL(curpcb)
lea _ASM_LABEL(tmpstk),%sp | goto a tmp stack
/* Schedule the vmspace and stack to be freed. */
movl %a0,%sp@- | exit2(l)
jbsr _C_LABEL(exit2)
lea %sp@(4),%sp | pop args
#if defined(LOCKDEBUG)
/* Acquire sched_lock */
jbsr _C_LABEL(sched_lock_idle)
#endif
jra _C_LABEL(cpu_switch)
/*
* void switch_lwp_exit(struct lwp *);
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.6 2003/08/07 16:28:19 agc Exp $ */
/* $NetBSD: vm_machdep.c,v 1.7 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.6 2003/08/07 16:28:19 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.7 2004/01/04 11:33:30 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -185,6 +185,13 @@ cpu_setfunc(l, func, arg)
pcb->pcb_regs[11] = (int)sf; /* SSP */
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
/* Nothing to do */
}
/*
* cpu_exit is called as the last action during exit.
*
@ -192,17 +199,12 @@ cpu_setfunc(l, func, arg)
* switch to another process thus we never return.
*/
void
cpu_exit(l, proc)
cpu_exit(l)
struct lwp *l;
int proc;
{
(void) splhigh();
uvmexp.swtch++;
if (proc)
switch_exit(l);
else
switch_lwp_exit(l);
switch_lwp_exit(l);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.73 2003/08/07 16:28:20 agc Exp $ */
/* $NetBSD: cpu.h,v 1.74 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -132,7 +132,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.71 2003/08/07 16:28:27 agc Exp $ */
/* $NetBSD: cpu.h,v 1.72 2004/01/04 11:33:30 jdolecek Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -253,7 +253,6 @@ extern int mips3_pg_cached;
* definitions of cpu-dependent requirements
* referenced in generic code
*/
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) panic("cpu_swapout: can't get here");
void cpu_intr(u_int32_t, u_int32_t, u_int32_t, u_int32_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.99 2003/11/26 08:36:51 he Exp $ */
/* $NetBSD: vm_machdep.c,v 1.100 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1992, 1993
@ -79,7 +79,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.99 2003/11/26 08:36:51 he Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.100 2004/01/04 11:33:30 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -240,6 +240,14 @@ cpu_swapin(l)
l->l_md.md_upte[i] = pte[i].pt_entry &~ x;
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
if ((l->l_md.md_flags & MDP_FPUSED) && l == fpcurlwp)
fpcurlwp = (struct lwp *)0;
}
/*
* cpu_exit is called as the last action during exit.
*
@ -249,18 +257,13 @@ cpu_swapin(l)
* into the middle of cpu_switch(), as if it were switching from proc0.
*/
void
cpu_exit(l, proc)
cpu_exit(l)
struct lwp *l;
int proc;
{
void switch_exit(struct lwp *, void (*)(struct lwp *));
if ((l->l_md.md_flags & MDP_FPUSED) && l == fpcurlwp)
fpcurlwp = (struct lwp *)0;
uvmexp.swtch++;
(void)splhigh();
switch_exit(l, proc ? exit2 : lwp_exit2);
switch_exit(l, lwp_exit2);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.28 2003/08/07 16:28:41 agc Exp $ */
/* $NetBSD: cpu.h,v 1.29 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -112,7 +112,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.16 2003/08/07 16:28:50 agc Exp $ */
/* $NetBSD: cpu.h,v 1.17 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -132,7 +132,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.25 2003/10/05 22:00:25 mycroft Exp $ */
/* $NetBSD: cpu.h,v 1.26 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -119,7 +119,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.37 2003/08/07 16:28:59 agc Exp $ */
/* $NetBSD: cpu.h,v 1.38 2004/01/04 11:33:30 jdolecek Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -72,7 +72,6 @@ extern struct cpu_info cpu_info_store;
*/
#define cpu_proc_fork(p1, p2) /* nothing */
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_number() 0
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.58 2003/10/19 17:45:35 cl Exp $ */
/* $NetBSD: vm_machdep.c,v 1.59 2004/01/04 11:33:30 jdolecek Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.58 2003/10/19 17:45:35 cl Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.59 2004/01/04 11:33:30 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -212,6 +212,15 @@ cpu_swapout(l)
fpu_lwp = 0;
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
/* If we were using the FPU, forget about it. */
if (fpu_lwp == l)
fpu_lwp = 0;
}
/*
* cpu_exit is called as the last action during exit.
*
@ -220,31 +229,22 @@ cpu_swapout(l)
* jumps into switch() to wait for another process to wake up.
*/
void
cpu_exit(arg, proc)
cpu_exit(arg)
struct lwp *arg;
int proc;
{
extern struct user *proc0paddr;
register struct lwp *l __asm("r3");
uvmexp.swtch++;
/* Copy arg into a register. */
movd(arg, l);
/* If we were using the FPU, forget about it. */
if (fpu_lwp == l)
fpu_lwp = 0;
/* Switch to temporary stack and address space. */
lprd(sp, INTSTACK);
load_ptb(proc0paddr->u_pcb.pcb_ptb);
/* Schedule the vmspace and stack to be freed. */
(void) splhigh();
if (proc) /* XXXJRT FRAGILE! USE A REGISTER! */
exit2(l);
else
lwp_exit2(l);
lwp_exit2(l); /* XXXJRT FRAGILE! USE A REGISTER! */
/* Don't update pcb in cpu_switch. */
curlwp = NULL;

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.4 2003/12/30 12:33:18 pk Exp $ */
/* $NetBSD: machdep.c,v 1.5 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@ -138,13 +138,13 @@ sendsig(int sig, const sigset_t *mask, u_long code)
}
void
cpu_wait(struct lwp *p)
cpu_lwp_free(struct lwp *l, int proc)
{
panic("cpu_wait");
panic("cpu_lwp_free");
}
void
cpu_exit(struct lwp *p, int a)
cpu_exit(struct lwp *l)
{
panic("cpu_exit");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.38 2003/11/21 18:07:29 matt Exp $ */
/* $NetBSD: cpu.h,v 1.39 2004/01/04 11:33:30 jdolecek Exp $ */
/*
* Copyright (C) 1999 Wolfgang Solfrank.
@ -268,7 +268,6 @@ mfpvr(void)
#define LWP_PC(l) (trapframe(l)->srr0)
#define cpu_swapout(p)
#define cpu_wait(p)
#define cpu_proc_fork(p1, p2)
extern int powersave;

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.57 2003/09/27 04:44:42 matt Exp $ */
/* $NetBSD: vm_machdep.c,v 1.58 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.57 2003/09/27 04:44:42 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.58 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_altivec.h"
#include "opt_multiprocessor.h"
@ -214,19 +214,9 @@ pagemove(caddr_t from, caddr_t to, size_t size)
pmap_update(pmap_kernel());
}
/*
* cpu_exit is called as the last action during exit.
*
* 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(struct lwp *l, int proc)
cpu_lwp_free(struct lwp *l, int proc)
{
/* This is in locore_subr.S */
void switch_exit(struct lwp *, void (*)(struct lwp *));
#if defined(PPC_HAVE_FPU) || defined(ALTIVEC)
struct pcb *pcb = &l->l_addr->u_pcb;
#endif
@ -240,8 +230,24 @@ cpu_exit(struct lwp *l, int proc)
save_vec_lwp(l);
#endif
}
/*
* cpu_exit is called as the last action during exit.
*
* 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(struct lwp *l)
{
/* This is in locore_subr.S */
void switch_exit(struct lwp *, void (*)(struct lwp *));
splsched();
switch_exit(l, proc ? exit2 : lwp_exit2);
switch_exit(l, lwp_exit2);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.32 2003/08/07 16:29:28 agc Exp $ */
/* $NetBSD: cpu.h,v 1.33 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -104,7 +104,6 @@ extern struct cpu_info cpu_info_store;
* definitions of cpu-dependent requirements
* referenced in generic code
*/
#define cpu_wait(p) /* nothing */
#define cpu_number() 0
/*
* Can't swapout u-area, (__SWAP_BROKEN)

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.39 2003/11/15 23:47:58 uwe Exp $ */
/* $NetBSD: vm_machdep.c,v 1.40 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 1982, 1986 The Regents of the University of California.
@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.39 2003/11/15 23:47:58 uwe Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.40 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_kstack_debug.h"
@ -302,6 +302,13 @@ cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
sf->sf_sr = PSL_MD; /* kernel mode, interrupt enable */
}
void
cpu_lwp_free(struct lwp *l)
{
/* Nothing to do */
}
/*
* void cpu_exit(struct lwp *l):
* + Change kernel context to lwp0's one.
@ -309,12 +316,11 @@ cpu_setfunc(struct lwp *l, void (*func)(void *), void *arg)
* + switch to another process.
*/
void
cpu_exit(struct lwp *l, int proc)
cpu_exit(struct lwp *l)
{
struct switchframe *sf;
splsched();
uvmexp.swtch++;
/* Switch to lwp0 stack */
curlwp = 0;
@ -330,10 +336,7 @@ cpu_exit(struct lwp *l, int proc)
"r"(sf->sf_r7_bank));
/* Schedule freeing process resources */
if (proc)
exit2(l);
else
lwp_exit2(l);
lwp_exit2(l);
cpu_switch(l, NULL);
/* NOTREACHED */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.11 2003/08/07 16:29:31 agc Exp $ */
/* $NetBSD: cpu.h,v 1.12 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@ -194,7 +194,6 @@ curcpu(void)
* definitions of cpu-dependent requirements
* referenced in generic code
*/
#define cpu_wait(p) /* nothing */
#define cpu_number() 0
#define cpu_proc_fork(p1, p2) /* nothing */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.7 2003/07/15 03:36:01 lukem Exp $ */
/* $NetBSD: vm_machdep.c,v 1.8 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright 2002 Wasabi Systems, Inc.
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.7 2003/07/15 03:36:01 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.8 2004/01/04 11:33:31 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -135,6 +135,13 @@ cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
#endif
}
void
cpu_lwp_free(struct lwp *l, int proc)
{
/* Nothing to do */
}
/*
* cpu_exit is called as the last action during exit.
*
@ -142,15 +149,12 @@ cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred,
* switch to another LWP thus we never return.
*/
void
cpu_exit(struct lwp *l, int proc)
cpu_exit(struct lwp *l)
{
extern volatile void switch_exit(struct lwp *, void (*)(struct lwp *));
pmap_deactivate(l);
(void) splhigh();
uvmexp.swtch++;
switch_exit(l, proc ? exit2 : lwp_exit2);
switch_exit(l, lwp_exit2);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.65 2003/11/08 15:19:20 tsutsui Exp $ */
/* $NetBSD: cpu.h,v 1.66 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1992, 1993
@ -86,7 +86,6 @@
#define cpu_swapin(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_number() (cpuinfo.ci_cpuid)
#define cpu_proc_fork(p1, p2) /* nothing */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.77 2003/07/15 00:05:10 lukem Exp $ */
/* $NetBSD: vm_machdep.c,v 1.78 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1996
@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.77 2003/07/15 00:05:10 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.78 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_multiprocessor.h"
@ -308,20 +308,10 @@ cpu_lwp_fork(l1, l2, stack, stacksize, func, arg)
}
/*
* cpu_exit is called as the last action during exit.
*
* We clean up the FPU state 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.
*
* If proc==0, we're an exiting lwp and arrange to call lwp_exit2() instead
* of exit2().
* Cleanup FPU state.
*/
void
cpu_exit(l, proc)
struct lwp *l;
int proc;
cpu_lwp_free(struct lwp *l, int proc)
{
struct fpstate *fs;
@ -347,7 +337,24 @@ cpu_exit(l, proc)
l->l_md.md_fpstate = NULL;
free((void *)fs, M_SUBPROC);
}
switchexit(l, proc ? exit2 : lwp_exit2);
}
/*
* cpu_exit is called as the last action during exit.
*
* We just call switchexit() with the old lwp
* 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.
*
* If proc==0, we're an exiting lwp and arrange to call lwp_exit2() instead
* of exit2().
*/
void
cpu_exit(l)
struct lwp *l;
{
switchexit(l, lwp_exit2);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.40 2003/11/25 05:14:58 cdi Exp $ */
/* $NetBSD: cpu.h,v 1.41 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1992, 1993
@ -136,7 +136,6 @@ extern struct cpu_info *cpus;
*/
#define cpu_swapin(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_wait(p) /* nothing */
#if 1
#define cpu_number() 0
#else

View File

@ -1,4 +1,4 @@
/* $NetBSD: vm_machdep.c,v 1.52 2003/12/02 22:44:17 martin Exp $ */
/* $NetBSD: vm_machdep.c,v 1.53 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.52 2003/12/02 22:44:17 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.53 2004/01/04 11:33:31 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -330,16 +330,8 @@ cpu_setfunc(l, func, arg)
npcb->pcb_sp = (long)rp - STACK_OFFSET;
}
/*
* cpu_exit is called as the last action during exit.
*
* 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(l, proc)
cpu_lwp_free(l, proc)
struct lwp *l;
int proc;
{
@ -352,7 +344,21 @@ cpu_exit(l, proc)
}
free((void *)fs, M_SUBPROC);
}
switchexit(l, proc);
}
/*
* cpu_exit is called as the last action during exit.
*
* 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(l)
struct lwp *l;
{
switchexit(l, 0);
/* NOTREACHED */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.34 2003/09/22 17:11:46 tsutsui Exp $ */
/* $NetBSD: cpu.h,v 1.35 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -123,7 +123,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_number() 0
#define cpu_wait(p) /* nothing */
#define cpu_swapin(p) /* nothing */
#define cpu_swapout(p) /* nothing */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.6 2003/09/21 14:41:34 cl Exp $ */
/* $NetBSD: cpu.h,v 1.7 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@ -120,7 +120,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_number() 0
#define cpu_wait(p) /* nothing */
#define cpu_swapin(p) /* nothing */
#define cpu_swapout(p) /* nothing */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.66 2003/03/01 21:51:59 matt Exp $ */
/* $NetBSD: cpu.h,v 1.67 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden
@ -65,7 +65,6 @@
#include <machine/psl.h>
#define enablertclock()
#define cpu_wait(p)
/*
* All cpu-dependent info is kept in this struct. Pointer to the

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr.S,v 1.9 2003/11/10 08:51:52 wiz Exp $ */
/* $NetBSD: subr.S,v 1.10 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
@ -456,9 +456,6 @@ JSBENTRY(Swtchto)
ENTRY(cpu_exit,0)
movl 4(%ap),%r6 # Process pointer in %r6
pushl %r6
calls $1,_C_LABEL(pmap_deactivate)
mtpr $IPL_CLOCK,$PR_IPL # Block almost everything
mfpr $PR_SSP,%r7 # get cpu_info ptr
movl CI_EXIT(%r7),%r8 # scratch page address
@ -467,7 +464,7 @@ ENTRY(cpu_exit,0)
mtpr %r8,$PR_PCBB # new PCB
mtpr %r7,$PR_SSP # In case...
pushl %r6
calls $1,_C_LABEL(exit2) # release last resources.
calls $1,_C_LABEL(lwp_exit2) # release last resources.
mtpr $IPL_HIGH,$PR_IPL # block all types of interrupts
#if defined(LOCKDEBUG)
calls $0,_C_LABEL(sched_lock_idle)

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.h,v 1.29 2003/08/07 16:30:26 agc Exp $ */
/* $NetBSD: cpu.h,v 1.30 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1990, 1993
@ -118,7 +118,6 @@ extern struct cpu_info cpu_info_store;
* referenced in generic code
*/
#define cpu_swapin(p) /* nothing */
#define cpu_wait(p) /* nothing */
#define cpu_swapout(p) /* nothing */
#define cpu_number() 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.229 2004/01/01 00:00:05 mycroft Exp $ */
/* $NetBSD: init_main.c,v 1.230 2004/01/04 11:33:31 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.229 2004/01/01 00:00:05 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.230 2004/01/04 11:33:31 jdolecek Exp $");
#include "fs_nfs.h"
#include "opt_nfsserver.h"
@ -569,10 +569,6 @@ main(void)
if (kthread_create1(uvm_pageout, NULL, NULL, "pagedaemon"))
panic("fork pagedaemon");
/* Create the process reaper kernel thread. */
if (kthread_create1(reaper, NULL, NULL, "reaper"))
panic("fork reaper");
/* Create the filesystem syncer kernel thread. */
if (kthread_create1(sched_sync, NULL, NULL, "ioflush"))
panic("fork syncer");

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_exit.c,v 1.132 2004/01/03 19:43:55 jdolecek Exp $ */
/* $NetBSD: kern_exit.c,v 1.133 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.132 2004/01/03 19:43:55 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.133 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_ktrace.h"
#include "opt_perfctrs.h"
@ -245,9 +245,15 @@ exit1(struct lwp *l, int rv)
p->p_sigctx.ps_sigcheck = 0;
timers_free(p, TIMERS_ALL);
if (sa || (p->p_nlwps > 1))
if (sa || (p->p_nlwps > 1)) {
exit_lwps(l);
/*
* Collect thread u-areas.
*/
uvm_uarea_drain(FALSE);
}
#if defined(__HAVE_RAS)
ras_purgeall(p);
#endif
@ -366,6 +372,38 @@ exit1(struct lwp *l, int rv)
}
proclist_unlock_write(s);
/*
* Deactivate the address space before the vmspace is
* freed. Note that we will continue to run on this
* vmspace's context until the switch to the idle process.
*/
pmap_deactivate(l);
/*
* Free the VM resources we're still holding on to.
* We must do this from a valid thread because doing
* so may block. This frees vmspace, which we don't
* need anymore. The only remaining lwp is the one
* we run at this moment, nothing runs in userland
* anymore.
*/
uvm_proc_exit(p);
/*
* Give machine-dependent code a chance to free any
* MD LWP resources while we can still block. This must be done
* before uvm_lwp_exit(), in case these resources are in the
* PCB.
* THIS IS LAST BLOCKING OPERATION.
*/
#ifndef __NO_CPU_LWP_FREE
cpu_lwp_free(l, 1);
#endif
/*
* NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
*/
/*
* Save exit status and final rusage info, adding in child rusage
* info and self times.
@ -378,24 +416,33 @@ exit1(struct lwp *l, int rv)
ruadd(p->p_ru, &p->p_stats->p_cru);
/*
* NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
*/
/*
* Move proc 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_dead member), and
* wake up the reaper when we do.
* Changing the state to SDEAD stops it being found by pfind().
* Move proc from allproc to zombproc, it's now ready
* to be collected by parent. Remaining lwp resources
* will be freed in lwp_exit2() once we'd switch to idle
* context.
* Changing the state to SZOMB stops it being found by pfind().
*/
s = proclist_lock_write();
p->p_stat = SDEAD;
p->p_nrlwps--;
l->l_stat = LSDEAD;
LIST_REMOVE(p, p_list);
LIST_INSERT_HEAD(&zombproc, p, p_list);
p->p_stat = SZOMB;
LIST_REMOVE(l, l_list);
l->l_flag |= L_DETACHED;
l->l_flag |= L_DETACHED|L_PROCEXIT; /* detached from proc too */
l->l_stat = LSDEAD;
p->p_nrlwps--;
p->p_nlwps--;
/* Put in front of parent's sibling list for parent to collect it */
q = p->p_pptr;
q->p_nstopchild++;
if (LIST_FIRST(&q->p_children) != p) {
/* Put child where it can be found quickly */
LIST_REMOVE(p, p_sibling);
LIST_INSERT_HEAD(&q->p_children, p, p_sibling);
}
proclist_unlock_write(s);
/*
@ -422,6 +469,7 @@ exit1(struct lwp *l, int rv)
if (p->p_pptr->p_flag & P_NOCLDWAIT) {
struct proc *pp = p->p_pptr;
proc_reparent(p, initproc);
/*
* If this was the last child of our parent, notify
* parent, so in case he was wait(2)ing, he will
@ -431,6 +479,11 @@ exit1(struct lwp *l, int rv)
wakeup(pp);
}
/* Wake up the parent so it can get exit status. */
if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0)
exit_psignal(p, p->p_pptr);
wakeup(p->p_pptr);
/*
* Release the process's signal state.
*/
@ -454,18 +507,23 @@ exit1(struct lwp *l, int rv)
/* This process no longer needs to hold the kernel lock. */
KERNEL_PROC_UNLOCK(l);
#ifdef DEBUG
/* Nothing should use the process link anymore */
l->l_proc = NULL;
#endif
/*
* 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.
* using the dead lwp's stack, lwp_exit2() will be called
* to arrange for the resources to be released.
*
* Note that cpu_exit() will end with a call equivalent to
* cpu_switch(), finishing our execution (pun intended).
*/
cpu_exit(l, 1);
uvmexp.swtch++;
cpu_exit(l);
}
void
@ -548,123 +606,6 @@ lwp_exit_hook(struct lwp *l, void *arg)
lwp_exit(l);
}
/*
* We are called from cpu_exit() once it is safe to schedule the
* dead process's resources to be freed (i.e., once we've switched to
* the idle PCB for the current CPU).
*
* 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_dead member), and wake up the reaper.
*/
void
exit2(struct lwp *l)
{
struct proc *p = l->l_proc;
simple_lock(&deadproc_slock);
SLIST_INSERT_HEAD(&deadprocs, p, p_dead);
simple_unlock(&deadproc_slock);
/* lwp_exit2() will wake up deadproc for us. */
lwp_exit2(l);
}
/*
* 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(void *arg)
{
struct proc *p, *parent;
struct lwp *l;
KERNEL_PROC_UNLOCK(curlwp);
for (;;) {
simple_lock(&deadproc_slock);
p = SLIST_FIRST(&deadprocs);
l = LIST_FIRST(&deadlwp);
if (p == NULL && l == NULL) {
/* No work for us; go to sleep until someone exits. */
(void) ltsleep(&deadprocs, PVM|PNORELOCK,
"reaper", 0, &deadproc_slock);
continue;
}
if (l != NULL ) {
p = l->l_proc;
/* Remove lwp from the deadlwp list. */
LIST_REMOVE(l, l_list);
simple_unlock(&deadproc_slock);
KERNEL_PROC_LOCK(curlwp);
/*
* 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_lwp_exit(), in case these resources are in the
* PCB.
*/
cpu_wait(l);
/*
* Free the VM resources we're still holding on to.
*/
uvm_lwp_exit(l);
l->l_stat = LSZOMB;
if (l->l_flag & L_DETACHED) {
/* Nobody waits for detached LWPs. */
LIST_REMOVE(l, l_sibling);
p->p_nlwps--;
pool_put(&lwp_pool, l);
} else {
p->p_nzlwps++;
wakeup(&p->p_nlwps);
}
/* XXXNJW where should this be with respect to
* the wakeup() above? */
KERNEL_PROC_UNLOCK(curlwp);
} else {
/* Remove proc from the deadproc list. */
SLIST_REMOVE_HEAD(&deadprocs, p_dead);
simple_unlock(&deadproc_slock);
KERNEL_PROC_LOCK(curlwp);
/*
* Free the VM resources we're still holding on to.
* We must do this from a valid thread because doing
* so may block.
*/
uvm_proc_exit(p);
/* Process is now a true zombie. */
p->p_stat = SZOMB;
parent = p->p_pptr;
parent->p_nstopchild++;
if (LIST_FIRST(&parent->p_children) != p) {
/* Put child where it can be found quickly */
LIST_REMOVE(p, p_sibling);
LIST_INSERT_HEAD(&parent->p_children,
p, p_sibling);
}
/* Wake up the parent so it can get exit status. */
if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0)
exit_psignal(p, p->p_pptr);
KERNEL_PROC_UNLOCK(curlwp);
wakeup(p->p_pptr);
}
}
}
int
sys_wait4(struct lwp *l, void *v, register_t *retval)
{
@ -693,6 +634,11 @@ sys_wait4(struct lwp *l, void *v, register_t *retval)
return 0;
}
/*
* Collect child u-areas.
*/
uvm_uarea_drain(FALSE);
retval[0] = child->p_pid;
if (child->p_stat == SZOMB) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_lwp.c,v 1.18 2004/01/03 20:10:01 jdolecek Exp $ */
/* $NetBSD: kern_lwp.c,v 1.19 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.18 2004/01/03 20:10:01 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.19 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_multiprocessor.h"
@ -57,8 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.18 2004/01/03 20:10:01 jdolecek Exp $
#include <uvm/uvm_extern.h>
struct lwplist alllwp;
struct lwplist deadlwp;
struct lwplist zomblwp;
#define LWP_DEBUG
@ -382,7 +380,7 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lwpid_t *departed, int flags)
struct proc *p = l->l_proc;
struct lwp *l2, *l3;
int nfound, error, s, wpri;
int nfound, error, wpri;
static const char waitstr1[] = "lwpwait";
static const char waitstr2[] = "lwpwait2";
@ -406,10 +404,6 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lwpid_t *departed, int flags)
if (departed)
*departed = l2->l_lid;
s = proclist_lock_write();
LIST_REMOVE(l2, l_zlist); /* off zomblwp */
proclist_unlock_write(s);
simple_lock(&p->p_lock);
LIST_REMOVE(l2, l_sibling);
p->p_nlwps--;
@ -563,17 +557,18 @@ lwp_exit(struct lwp *l)
DPRINTF(("lwp_exit: %d.%d calling exit1()\n",
p->p_pid, l->l_lid));
exit1(l, 0);
/* NOTREACHED */
}
s = proclist_lock_write();
LIST_REMOVE(l, l_list);
if ((l->l_flag & L_DETACHED) == 0) {
DPRINTF(("lwp_exit: %d.%d going on zombie list\n", p->p_pid,
l->l_lid));
LIST_INSERT_HEAD(&zomblwp, l, l_zlist);
}
proclist_unlock_write(s);
/* Free MD LWP resources */
#ifndef __NO_CPU_LWP_FREE
cpu_lwp_free(l, 0);
#endif
simple_lock(&p->p_lock);
p->p_nrlwps--;
simple_unlock(&p->p_lock);
@ -584,20 +579,45 @@ lwp_exit(struct lwp *l)
KERNEL_PROC_UNLOCK(l);
/* cpu_exit() will not return */
cpu_exit(l, 0);
cpu_exit(l);
}
/*
* We are called from cpu_exit() once it is safe to schedule the
* dead process's resources to be freed (i.e., once we've switched to
* the idle PCB for the current CPU).
*
* 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.
*/
void
lwp_exit2(struct lwp *l)
{
struct proc *p;
simple_lock(&deadproc_slock);
LIST_INSERT_HEAD(&deadlwp, l, l_list);
simple_unlock(&deadproc_slock);
/*
* Free the VM resources we're still holding on to.
*/
uvm_lwp_exit(l);
wakeup(&deadprocs);
l->l_stat = LSZOMB;
if (l->l_flag & L_DETACHED) {
/* Nobody waits for detached LWPs. */
LIST_REMOVE(l, l_sibling);
if ((l->l_flag & L_PROCEXIT) == 0) {
p = l->l_proc;
p->p_nlwps--;
}
pool_put(&lwp_pool, l);
} else {
p = l->l_proc;
p->p_nzlwps++;
wakeup(&p->p_nlwps);
}
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_proc.c,v 1.69 2003/11/17 22:52:09 cl Exp $ */
/* $NetBSD: kern_proc.c,v 1.70 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.69 2003/11/17 22:52:09 cl Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.70 2004/01/04 11:33:31 jdolecek Exp $");
#include "opt_kstack.h"
@ -133,17 +133,6 @@ struct proclist zombproc; /* resources have been freed */
*/
struct lock proclist_lock;
/*
* List of processes that has called exit, but need to be reaped.
* 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.
*/
struct simplelock deadproc_slock;
struct deadprocs deadprocs = SLIST_HEAD_INITIALIZER(deadprocs);
/*
* pid to proc lookup is done by indexing the pid_table array.
* Since pid numbers are only allocated when an empty slot
@ -229,8 +218,6 @@ procinit(void)
spinlockinit(&proclist_lock, "proclk", 0);
simple_lock_init(&deadproc_slock);
pid_table = malloc(INITIAL_PID_TABLE_SIZE * sizeof *pid_table,
M_PROC, M_WAITOK);
/* Set free list running through table...
@ -249,8 +236,6 @@ procinit(void)
#undef LINK_EMPTY
LIST_INIT(&alllwp);
LIST_INIT(&deadlwp);
LIST_INIT(&zomblwp);
uihashtbl =
hashinit(maxproc / 16, HASH_LIST, M_PROC, M_WAITOK, &uihash);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lwp.h,v 1.17 2004/01/02 18:52:17 cl Exp $ */
/* $NetBSD: lwp.h,v 1.18 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -52,7 +52,7 @@ struct lwp {
struct lwp *l_forw; /* Doubly-linked run/sleep queue. */
struct lwp *l_back;
LIST_ENTRY(lwp) l_list; /* Entry on list of all LWPs. */
LIST_ENTRY(lwp) l_zlist; /* Entry on zombie list. */
LIST_ENTRY(lwp) _l_nu1; /* Unused, was entry on zombie list. */
struct proc *l_proc; /* Process with which we are associated. */
@ -98,8 +98,6 @@ struct lwp {
LIST_HEAD(lwplist, lwp); /* a list of LWPs */
extern struct lwplist alllwp; /* List of all LWPs. */
extern struct lwplist deadlwp; /* */
extern struct lwplist zomblwp;
extern struct pool lwp_pool; /* memory pool for LWPs */
extern struct pool lwp_uc_pool; /* memory pool for LWP startup args */
@ -111,6 +109,7 @@ extern struct lwp lwp0; /* LWP for proc0 */
#define L_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
#define L_SINTR 0x00080 /* Sleep is interruptible. */
#define L_TIMEOUT 0x00400 /* Timing out during sleep. */
#define L_PROCEXIT 0x00800 /* In process exit, l_proc no longer valid */
#define L_BIGLOCK 0x80000 /* LWP needs kernel "big lock" to run */
#define L_SA 0x100000 /* Scheduler activations LWP */
#define L_SA_UPCALL 0x200000 /* SA upcall is pending */

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.185 2003/12/24 22:53:59 manu Exp $ */
/* $NetBSD: proc.h,v 1.186 2004/01/04 11:33:31 jdolecek Exp $ */
/*-
* Copyright (c) 1986, 1989, 1991, 1993
@ -177,7 +177,7 @@ struct proc {
char p_pad1[3];
pid_t p_pid; /* Process identifier. */
SLIST_ENTRY(proc) p_dead; /* Processes waiting for reaper */
SLIST_ENTRY(proc) _p_nu3; /* unused: was link to deadproc list */
LIST_ENTRY(proc) p_pglist; /* l: List of processes in pgrp. */
struct proc *p_pptr; /* l: Pointer to parent process. */
LIST_ENTRY(proc) p_sibling; /* l: List of sibling processes. */
@ -450,9 +450,7 @@ int ltsleep(const void *, int, const char *, int,
__volatile struct simplelock *);
void wakeup(const void *);
void wakeup_one(const void *);
void reaper(void *);
void exit1(struct lwp *, int);
void exit2(struct lwp *);
int find_stopped_child(struct proc *, pid_t, int, struct proc **);
struct proc *proc_alloc(void);
void proc0_insert(struct proc *, struct lwp *, struct pgrp *, struct session *);
@ -467,15 +465,10 @@ int pgid_in_session(struct proc *, pid_t);
#ifndef cpu_idle
void cpu_idle(void);
#endif
void cpu_exit(struct lwp *, int);
void cpu_exit(struct lwp *);
void cpu_lwp_fork(struct lwp *, struct lwp *, void *, size_t,
void (*)(void *), void *);
/*
* XXX: use __P() to allow ports to have as a #define.
* XXX: we need a better way to solve this.
*/
void cpu_wait __P((struct lwp *));
void cpu_lwp_free(struct lwp *, int);
void child_return(void *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_extern.h,v 1.87 2003/12/18 15:02:04 pk Exp $ */
/* $NetBSD: uvm_extern.h,v 1.88 2004/01/04 11:33:32 jdolecek Exp $ */
/*
*
@ -576,7 +576,7 @@ boolean_t uvm_kernacc __P((caddr_t, size_t, int));
__dead void uvm_scheduler __P((void)) __attribute__((noreturn));
void uvm_swapin __P((struct lwp *));
boolean_t uvm_uarea_alloc(vaddr_t *);
void uvm_uarea_free(vaddr_t);
void uvm_uarea_drain(boolean_t);
int uvm_vslock __P((struct proc *, caddr_t, size_t,
vm_prot_t));
void uvm_vsunlock __P((struct proc *, caddr_t, size_t));

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_glue.c,v 1.74 2003/12/30 12:33:24 pk Exp $ */
/* $NetBSD: uvm_glue.c,v 1.75 2004/01/04 11:33:32 jdolecek Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.74 2003/12/30 12:33:24 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.75 2004/01/04 11:33:32 jdolecek Exp $");
#include "opt_kgdb.h"
#include "opt_kstack.h"
@ -99,6 +99,8 @@ void *uvm_uareas;
int uvm_nuarea;
struct simplelock uvm_uareas_slock = SIMPLELOCK_INITIALIZER;
static void uvm_uarea_free(vaddr_t);
/*
* XXXCDC: do these really belong here?
*/
@ -334,8 +336,8 @@ uvm_uarea_alloc(vaddr_t *uaddrp)
#endif
simple_lock(&uvm_uareas_slock);
uaddr = (vaddr_t)uvm_uareas;
if (uaddr) {
if (uvm_nuarea > 0) {
uaddr = (vaddr_t)uvm_uareas;
uvm_uareas = *(void **)uvm_uareas;
uvm_nuarea--;
simple_unlock(&uvm_uareas_slock);
@ -349,23 +351,43 @@ uvm_uarea_alloc(vaddr_t *uaddrp)
}
/*
* uvm_uarea_free: free a u-area
* uvm_uarea_free: free a u-area; never blocks
*/
static void
uvm_uarea_free(vaddr_t uaddr)
{
simple_lock(&uvm_uareas_slock);
*(void **)uaddr = uvm_uareas;
uvm_uareas = (void *)uaddr;
uvm_nuarea++;
simple_unlock(&uvm_uareas_slock);
}
/*
* uvm_uarea_drain: return memory of u-areas over limit
* back to system
*/
void
uvm_uarea_free(vaddr_t uaddr)
uvm_uarea_drain(boolean_t empty)
{
int leave = empty ? 0 : UVM_NUAREA_MAX;
vaddr_t uaddr;
if (uvm_nuarea <= leave)
return;
simple_lock(&uvm_uareas_slock);
if (uvm_nuarea < UVM_NUAREA_MAX) {
*(void **)uaddr = uvm_uareas;
uvm_uareas = (void *)uaddr;
uvm_nuarea++;
simple_unlock(&uvm_uareas_slock);
} else {
while(uvm_nuarea > leave) {
uaddr = (vaddr_t)uvm_uareas;
uvm_uareas = *(void **)uvm_uareas;
uvm_nuarea--;
simple_unlock(&uvm_uareas_slock);
uvm_km_free(kernel_map, uaddr, USPACE);
simple_lock(&uvm_uareas_slock);
}
simple_unlock(&uvm_uareas_slock);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_pdaemon.c,v 1.56 2003/12/30 12:33:24 pk Exp $ */
/* $NetBSD: uvm_pdaemon.c,v 1.57 2004/01/04 11:33:32 jdolecek Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.56 2003/12/30 12:33:24 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.57 2004/01/04 11:33:32 jdolecek Exp $");
#include "opt_uvmhist.h"
@ -275,6 +275,12 @@ uvm_pageout(void *arg)
buf_drain(0);
pool_drain(0);
/*
* free any cached u-areas we don't need
*/
uvm_uarea_drain(TRUE);
}
/*NOTREACHED*/
}