diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1132d62dc532..494795333b6e 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_fork.c,v 1.92 2002/08/28 07:16:37 gmcgarry Exp $ */ +/* $NetBSD: kern_fork.c,v 1.93 2002/09/22 07:20:29 chs Exp $ */ /*- * Copyright (c) 1999, 2001 The NetBSD Foundation, Inc. @@ -78,7 +78,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.92 2002/08/28 07:16:37 gmcgarry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.93 2002/09/22 07:20:29 chs Exp $"); #include "opt_ktrace.h" #include "opt_systrace.h" @@ -232,14 +232,10 @@ fork1(struct proc *p1, int flags, int exitsig, void *stack, size_t stacksize, * Allocate virtual address space for the U-area now, while it * is still easy to abort the fork operation if we're out of * kernel virtual address space. The actual U-area pages will - * be allocated and wired in vm_fork(). + * be allocated and wired in uvm_fork(). */ -#ifndef USPACE_ALIGN -#define USPACE_ALIGN 0 -#endif - - uaddr = uvm_km_valloc_align(kernel_map, USPACE, USPACE_ALIGN); + uaddr = uvm_uarea_alloc(); if (__predict_false(uaddr == 0)) { (void)chgproccnt(uid, -1); nprocs--; diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 8a6174299a6a..3d24bd847840 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_extern.h,v 1.72 2002/09/15 16:54:29 chs Exp $ */ +/* $NetBSD: uvm_extern.h,v 1.73 2002/09/22 07:20:31 chs Exp $ */ /* * @@ -572,6 +572,8 @@ void uvm_init_limits __P((struct proc *)); boolean_t uvm_kernacc __P((caddr_t, size_t, int)); __dead void uvm_scheduler __P((void)) __attribute__((noreturn)); void uvm_swapin __P((struct proc *)); +vaddr_t uvm_uarea_alloc(void); +void uvm_uarea_free(vaddr_t); boolean_t uvm_useracc __P((caddr_t, size_t, int)); int uvm_vslock __P((struct proc *, caddr_t, size_t, vm_prot_t)); diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c index dc8e7bf8f515..8fc100f428f0 100644 --- a/sys/uvm/uvm_glue.c +++ b/sys/uvm/uvm_glue.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_glue.c,v 1.59 2002/07/02 20:27:48 yamt Exp $ */ +/* $NetBSD: uvm_glue.c,v 1.60 2002/09/22 07:20:32 chs Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -67,7 +67,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.59 2002/07/02 20:27:48 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.60 2002/09/22 07:20:32 chs Exp $"); #include "opt_kgdb.h" #include "opt_kstack.h" @@ -98,6 +98,10 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_glue.c,v 1.59 2002/07/02 20:27:48 yamt Exp $"); static void uvm_swapout __P((struct proc *)); +#define UVM_NUAREA_MAX 16 +void *uvm_uareas; +int uvm_nuarea; + /* * XXXCDC: do these really belong here? */ @@ -333,6 +337,7 @@ uvm_fork(p1, p2, shared, stack, stacksize, func, arg) * - we must run in a separate thread because freeing the vmspace * of the dead process may block. */ + void uvm_exit(p) struct proc *p; @@ -341,15 +346,56 @@ uvm_exit(p) uvmspace_free(p->p_vmspace); p->p_flag &= ~P_INMEM; - uvm_km_free(kernel_map, va, USPACE); + uvm_uarea_free(va); p->p_addr = NULL; } +/* + * uvm_uarea_alloc: allocate a u-area + */ + +vaddr_t +uvm_uarea_alloc(void) +{ + vaddr_t uaddr; + +#ifndef USPACE_ALIGN +#define USPACE_ALIGN 0 +#endif + + uaddr = (vaddr_t)uvm_uareas; + if (uaddr) { + uvm_uareas = *(void **)uvm_uareas; + uvm_nuarea--; + } else { + uaddr = uvm_km_valloc_align(kernel_map, USPACE, USPACE_ALIGN); + } + return uaddr; +} + +/* + * uvm_uarea_free: free a u-area + */ + +void +uvm_uarea_free(vaddr_t uaddr) +{ + + if (uvm_nuarea < UVM_NUAREA_MAX) { + *(void **)uaddr = uvm_uareas; + uvm_uareas = (void *)uaddr; + uvm_nuarea++; + } else { + uvm_km_free(kernel_map, uaddr, USPACE); + } +} + /* * uvm_init_limit: init per-process VM limits * * - called for process 0 and then inherited by all others. */ + void uvm_init_limits(p) struct proc *p; @@ -515,6 +561,7 @@ loop: * are swapped... otherwise the longest-sleeping or stopped process * is swapped, otherwise the longest resident process... */ + void uvm_swapout_threads() {