Index: alpha/alpha/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v retrieving revision 1.95 diff -u -r1.95 pmap.c --- alpha/alpha/pmap.c 4 Jul 2002 01:53:09 -0000 1.95 +++ alpha/alpha/pmap.c 5 Jul 2002 06:07:31 -0000 @@ -901,160 +901,6 @@ } /* - * Create the UPAGES for a new process. - * This routine directly affects the fork perf for a process. - */ -void -pmap_new_proc(struct proc *p) -{ - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - pt_entry_t *ptek, oldpte; - - /* - * allocate object for the upage - */ - upobj = p->p_upages_obj; - if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); - p->p_upages_obj = upobj; - } - - /* get a kernel virtual address for the UPAGES for this proc */ - up = (vm_offset_t)p->p_uarea; - if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); - if (up == 0) - panic("pmap_new_proc: upage allocation failed"); - p->p_uarea = (struct user *)up; - } - - ptek = vtopte(up); - - for (i = 0; i < UAREA_PAGES; i++) { - /* - * Get a kernel page for the uarea - */ - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - - /* - * Wire the page - */ - m->wire_count++; - cnt.v_wire_count++; - - /* - * Enter the page into the kernel address space. - */ - oldpte = ptek[i]; - ptek[i] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(m)) - | PG_ASM | PG_KRE | PG_KWE | PG_V; - if (oldpte) - pmap_invalidate_page(kernel_pmap, up + i * PAGE_SIZE); - - vm_page_wakeup(m); - vm_page_flag_clear(m, PG_ZERO); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - m->valid = VM_PAGE_BITS_ALL; - } -} - -/* - * Dispose the UPAGES for a process that has exited. - * This routine directly impacts the exit perf of a process. - */ -void -pmap_dispose_proc(p) - struct proc *p; -{ - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - pt_entry_t *ptek; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - ptek = vtopte(up); - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_dispose_proc: upage already missing?"); - vm_page_busy(m); - ptek[i] = 0; - pmap_invalidate_page(kernel_pmap, up + i * PAGE_SIZE); - vm_page_unwire(m, 0); - vm_page_free(m); - } - - /* - * If the process got swapped out some of its UPAGES might have gotten - * swapped. Just get rid of the object to clean up the swap use - * proactively. NOTE! might block waiting for paging I/O to complete. - */ - if (upobj->type == OBJT_SWAP) { - p->p_upages_obj = NULL; - vm_object_deallocate(upobj); - } -} - -/* - * Allow the UPAGES for a process to be prejudicially paged out. - */ -void -pmap_swapout_proc(p) - struct proc *p; -{ - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_swapout_proc: upage already missing?"); - vm_page_dirty(m); - vm_page_unwire(m, 0); - pmap_kremove(up + i * PAGE_SIZE); - } -} - -/* - * Bring the UPAGES for a specified process back in. - */ -void -pmap_swapin_proc(p) - struct proc *p; -{ - int i, rv; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - pmap_kenter(up + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); - if (m->valid != VM_PAGE_BITS_ALL) { - rv = vm_pager_get_pages(upobj, &m, 1, 0); - if (rv != VM_PAGER_OK) - panic("pmap_swapin_proc: cannot get upages for proc: %d\n", p->p_pid); - m = vm_page_lookup(upobj, i); - m->valid = VM_PAGE_BITS_ALL; - } - vm_page_wire(m); - vm_page_wakeup(m); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - } -} - -/* * Create the kernel stack for a new thread. * This routine directly affects the fork perf for a process and thread. */ Index: conf/newvers.sh =================================================================== RCS file: /home/ncvs/src/sys/conf/newvers.sh,v retrieving revision 1.47 diff -u -r1.47 newvers.sh --- conf/newvers.sh 2 Mar 2001 16:52:13 -0000 1.47 +++ conf/newvers.sh 1 Jul 2002 16:29:32 -0000 @@ -36,7 +36,7 @@ TYPE="FreeBSD" REVISION="5.0" -BRANCH="CURRENT" +BRANCH="XP" RELEASE="${REVISION}-${BRANCH}" VERSION="${TYPE} ${RELEASE}" Index: i386/i386/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v retrieving revision 1.332 diff -u -r1.332 pmap.c --- i386/i386/pmap.c 4 Jul 2002 19:53:24 -0000 1.332 +++ i386/i386/pmap.c 5 Jul 2002 06:07:56 -0000 @@ -820,176 +820,6 @@ } /* - * Create the Uarea stack for a new process. - * This routine directly affects the fork perf for a process. - */ -void -pmap_new_proc(struct proc *p) -{ -#ifdef I386_CPU - int updateneeded = 0; -#endif - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - pt_entry_t *ptek, oldpte; - - /* - * allocate object for the upage - */ - upobj = p->p_upages_obj; - if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); - p->p_upages_obj = upobj; - } - - /* get a kernel virtual address for the U area for this thread */ - up = (vm_offset_t)p->p_uarea; - if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); - if (up == 0) - panic("pmap_new_proc: upage allocation failed"); - p->p_uarea = (struct user *)up; - } - - ptek = vtopte(up); - - for (i = 0; i < UAREA_PAGES; i++) { - /* - * Get a kernel page for the uarea - */ - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - - /* - * Wire the page - */ - m->wire_count++; - cnt.v_wire_count++; - - /* - * Enter the page into the kernel address space. - */ - oldpte = ptek[i]; - ptek[i] = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag; - if (oldpte) { -#ifdef I386_CPU - updateneeded = 1; -#else - invlpg(up + i * PAGE_SIZE); -#endif - } - - vm_page_wakeup(m); - vm_page_flag_clear(m, PG_ZERO); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - m->valid = VM_PAGE_BITS_ALL; - } -#ifdef I386_CPU - if (updateneeded) - invltlb(); -#endif -} - -/* - * Dispose the U-Area for a process that has exited. - * This routine directly impacts the exit perf of a process. - */ -void -pmap_dispose_proc(p) - struct proc *p; -{ - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - pt_entry_t *ptek; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - ptek = vtopte(up); - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_dispose_proc: upage already missing?"); - vm_page_busy(m); - ptek[i] = 0; -#ifndef I386_CPU - invlpg(up + i * PAGE_SIZE); -#endif - vm_page_unwire(m, 0); - vm_page_free(m); - } -#ifdef I386_CPU - invltlb(); -#endif - - /* - * If the process got swapped out some of its UPAGES might have gotten - * swapped. Just get rid of the object to clean up the swap use - * proactively. NOTE! might block waiting for paging I/O to complete. - */ - if (upobj->type == OBJT_SWAP) { - p->p_upages_obj = NULL; - vm_object_deallocate(upobj); - } -} - -/* - * Allow the U_AREA for a process to be prejudicially paged out. - */ -void -pmap_swapout_proc(p) - struct proc *p; -{ - int i; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_swapout_proc: upage already missing?"); - vm_page_dirty(m); - vm_page_unwire(m, 0); - pmap_kremove(up + i * PAGE_SIZE); - } -} - -/* - * Bring the U-Area for a specified process back in. - */ -void -pmap_swapin_proc(p) - struct proc *p; -{ - int i, rv; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - pmap_kenter(up + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); - if (m->valid != VM_PAGE_BITS_ALL) { - rv = vm_pager_get_pages(upobj, &m, 1, 0); - if (rv != VM_PAGER_OK) - panic("pmap_swapin_proc: cannot get upage for proc: %d\n", p->p_pid); - m = vm_page_lookup(upobj, i); - m->valid = VM_PAGE_BITS_ALL; - } - vm_page_wire(m); - vm_page_wakeup(m); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - } -} - -/* * Create the kernel stack (including pcb for i386) for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. Index: ia64/ia64/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/ia64/ia64/pmap.c,v retrieving revision 1.66 diff -u -r1.66 pmap.c --- ia64/ia64/pmap.c 5 Jul 2002 01:27:35 -0000 1.66 +++ ia64/ia64/pmap.c 5 Jul 2002 06:08:13 -0000 @@ -707,154 +707,6 @@ } /* - * Create the U area for a new process. - * This routine directly affects the fork perf for a process. - */ -void -pmap_new_proc(struct proc *p) -{ - vm_page_t ma[UAREA_PAGES]; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - u_int i; - - /* - * Allocate object for the upage. - */ - upobj = p->p_upages_obj; - if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); - p->p_upages_obj = upobj; - } - - /* - * Get a kernel virtual address for the U area for this process. - */ - up = (vm_offset_t)p->p_uarea; - if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); - if (up == 0) - panic("pmap_new_proc: upage allocation failed"); - p->p_uarea = (struct user *)up; - } - - for (i = 0; i < UAREA_PAGES; i++) { - /* - * Get a uarea page. - */ - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - ma[i] = m; - - /* - * Wire the page. - */ - m->wire_count++; - cnt.v_wire_count++; - - vm_page_wakeup(m); - vm_page_flag_clear(m, PG_ZERO); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - m->valid = VM_PAGE_BITS_ALL; - } - - /* - * Enter the pages into the kernel address space. - */ - pmap_qenter(up, ma, UAREA_PAGES); -} - -/* - * Dispose the U area for a process that has exited. - * This routine directly impacts the exit perf of a process. - */ -void -pmap_dispose_proc(struct proc *p) -{ - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_dispose_proc: upage already missing?"); - vm_page_busy(m); - vm_page_unwire(m, 0); - vm_page_free(m); - } - pmap_qremove(up, UAREA_PAGES); - - /* - * If the process got swapped out some of its UPAGES might have gotten - * swapped. Just get rid of the object to clean up the swap use - * proactively. NOTE! might block waiting for paging I/O to complete. - */ - if (upobj->type == OBJT_SWAP) { - p->p_upages_obj = NULL; - vm_object_deallocate(upobj); - } -} - -/* - * Allow the U area for a process to be prejudicially paged out. - */ -void -pmap_swapout_proc(struct proc *p) -{ - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_swapout_proc: upage already missing?"); - vm_page_dirty(m); - vm_page_unwire(m, 0); - } - pmap_qremove(up, UAREA_PAGES); -} - -/* - * Bring the U area for a specified process back in. - */ -void -pmap_swapin_proc(struct proc *p) -{ - vm_page_t ma[UAREA_PAGES]; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int rv; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - if (m->valid != VM_PAGE_BITS_ALL) { - rv = vm_pager_get_pages(upobj, &m, 1, 0); - if (rv != VM_PAGER_OK) - panic("pmap_swapin_proc: cannot get upage"); - m = vm_page_lookup(upobj, i); - m->valid = VM_PAGE_BITS_ALL; - } - ma[i] = m; - vm_page_wire(m); - vm_page_wakeup(m); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - } - pmap_qenter(up, ma, UAREA_PAGES); -} - -/* * Create the KSTACK for a new thread. * This routine directly affects the fork perf for a process/thread. */ Index: kern/kern_exit.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v retrieving revision 1.170 diff -u -r1.170 kern_exit.c --- kern/kern_exit.c 29 Jun 2002 17:26:18 -0000 1.170 +++ kern/kern_exit.c 5 Jul 2002 06:43:44 -0000 @@ -740,7 +740,6 @@ * release while still running in process context. */ vm_waitproc(p); - mtx_destroy(&p->p_mtx); uma_zfree(proc_zone, p); sx_xlock(&allproc_lock); nprocs--; Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.151 diff -u -r1.151 kern_fork.c --- kern/kern_fork.c 29 Jun 2002 17:26:18 -0000 1.151 +++ kern/kern_fork.c 5 Jul 2002 06:37:25 -0000 @@ -427,7 +427,6 @@ lastpid = trypid; p2 = newproc; - p2->p_state = PRS_NEW; /* protect against others */ p2->p_pid = trypid; LIST_INSERT_HEAD(&allproc, p2, p_list); LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); @@ -471,8 +470,6 @@ #define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) - bzero(&p2->p_startzero, - (unsigned) RANGEOF(struct proc, p_startzero, p_endzero)); bzero(&ke2->ke_startzero, (unsigned) RANGEOF(struct kse, ke_startzero, ke_endzero)); #if 0 /* bzero'd by the thread allocator */ @@ -482,7 +479,6 @@ bzero(&kg2->kg_startzero, (unsigned) RANGEOF(struct ksegrp, kg_startzero, kg_endzero)); - mtx_init(&p2->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); PROC_LOCK(p2); PROC_LOCK(p1); @@ -620,11 +616,6 @@ LIST_INSERT_AFTER(p1, p2, p_pglist); PGRP_UNLOCK(p1->p_pgrp); - LIST_INIT(&p2->p_children); - LIST_INIT(&td2->td_contested); /* XXXKSE only 1 thread? */ - - callout_init(&p2->p_itcallout, 0); - callout_init(&td2->td_slpcallout, 1); /* XXXKSE */ #ifdef KTRACE /* Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.139 diff -u -r1.139 kern_proc.c --- kern/kern_proc.c 30 Jun 2002 07:50:22 -0000 1.139 +++ kern/kern_proc.c 5 Jul 2002 06:39:21 -0000 @@ -58,6 +58,7 @@ #endif #include +#include #include #include #include @@ -76,6 +77,11 @@ static void orphanpg(struct pgrp *pg); +static void proc_ctor(void *mem, int size, void *arg); +static void proc_dtor(void *mem, int size, void *arg); +static void proc_init(void *mem, int size); +static void proc_fini(void *mem, int size); + /* * Other process lists */ @@ -91,6 +97,12 @@ uma_zone_t proc_zone; uma_zone_t ithread_zone; +static int active_procs; +static int cached_procs; +static int allocated_procs; + +#define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) + CTASSERT(sizeof(struct kinfo_proc) == KINFO_PROC_SIZE); /* @@ -107,11 +119,82 @@ LIST_INIT(&zombproc); pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); - proc_zone = uma_zcreate("PROC", sizeof (struct proc), NULL, NULL, - NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + proc_zone = uma_zcreate("PROC", sizeof (struct proc), + proc_ctor, proc_dtor, proc_init, proc_fini, + UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uihashinit(); } +/* + * Prepare a proc for use. + */ +static void +proc_ctor(void *mem, int size, void *arg) +{ + struct proc *p; + + KASSERT((size == sizeof(struct proc)), + ("size mismatch: %d != %d\n", size, sizeof(struct proc))); + p = (struct proc *)mem; + bzero(&p->p_startzero, + (unsigned) RANGEOF(struct proc, p_startzero, p_endzero)); + p->p_state = PRS_NEW; + mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); + LIST_INIT(&p->p_children); + callout_init(&p->p_itcallout, 0); + cached_procs--; + active_procs++; +} + +/* + * Reclaim a proc after use. + */ +static void +proc_dtor(void *mem, int size, void *arg) +{ + struct proc *p; + + KASSERT((size == sizeof(struct proc)), + ("size mismatch: %d != %d\n", size, sizeof(struct proc))); + p = (struct proc *)mem; + /* INVARIANTS checks go here */ + mtx_destroy(&p->p_mtx); + active_procs--; + cached_procs++; +} + +/* + * Initialize type-stable parts of a proc (when newly created). + */ +static void +proc_init(void *mem, int size) +{ + struct proc *p; + + KASSERT((size == sizeof(struct proc)), + ("size mismatch: %d != %d\n", size, sizeof(struct proc))); + p = (struct proc *)mem; + vm_proc_new(p); + cached_procs++; + allocated_procs++; +} + +/* + * Tear down type-stable parts of a proc (just before being discarded) + */ +static void +proc_fini(void *mem, int size) +{ + struct proc *p; + + KASSERT((size == sizeof(struct proc)), + ("size mismatch: %d != %d\n", size, sizeof(struct proc))); + p = (struct proc *)mem; + vm_proc_dispose(p); + cached_procs--; + allocated_procs--; +} + /* * KSE is linked onto the idle queue. */ @@ -1143,3 +1226,12 @@ SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, CTLFLAG_RW | CTLFLAG_ANYBODY, sysctl_kern_proc_args, "Process argument list"); + +SYSCTL_INT(_kern_proc, OID_AUTO, active, CTLFLAG_RD, + &active_procs, 0, "Number of active procs in system."); + +SYSCTL_INT(_kern_proc, OID_AUTO, cached, CTLFLAG_RD, + &cached_procs, 0, "Number of procs in proc cache."); + +SYSCTL_INT(_kern_proc, OID_AUTO, allocated, CTLFLAG_RD, + &allocated_procs, 0, "Number of procs in zone."); Index: kern/kern_thread.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.3 diff -u -r1.3 kern_thread.c --- kern/kern_thread.c 1 Jul 2002 03:15:16 -0000 1.3 +++ kern/kern_thread.c 5 Jul 2002 06:37:10 -0000 @@ -97,6 +97,8 @@ (unsigned)RANGEOF(struct thread, td_startzero, td_endzero)); td->td_state = TDS_NEW; td->td_flags |= TDF_UNBOUND; + LIST_INIT(&td->td_contested); + callout_init(&td->td_slpcallout, 1); cached_threads--; /* XXXSMP */ active_threads++; /* XXXSMP */ } Index: powerpc/powerpc/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/powerpc/powerpc/pmap.c,v retrieving revision 1.39 diff -u -r1.39 pmap.c --- powerpc/powerpc/pmap.c 29 Jun 2002 09:45:59 -0000 1.39 +++ powerpc/powerpc/pmap.c 5 Jul 2002 06:08:48 -0000 @@ -1170,61 +1170,6 @@ return (0); } -/* - * Create the uarea for a new process. - * This routine directly affects the fork perf for a process. - */ -void -pmap_new_proc(struct proc *p) -{ - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - u_int i; - - /* - * Allocate the object for the upages. - */ - upobj = p->p_upages_obj; - if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); - p->p_upages_obj = upobj; - } - - /* - * Get a kernel virtual address for the uarea for this process. - */ - up = (vm_offset_t)p->p_uarea; - if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); - if (up == 0) - panic("pmap_new_proc: upage allocation failed"); - p->p_uarea = (struct user *)up; - } - - for (i = 0; i < UAREA_PAGES; i++) { - /* - * Get a uarea page. - */ - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - - /* - * Wire the page. - */ - m->wire_count++; - - /* - * Enter the page into the kernel address space. - */ - pmap_kenter(up + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); - - vm_page_wakeup(m); - vm_page_flag_clear(m, PG_ZERO); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - m->valid = VM_PAGE_BITS_ALL; - } -} - void pmap_object_init_pt(pmap_t pm, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size, int limit) @@ -1515,18 +1460,6 @@ pmap_remove(pm, sva, eva); } -void -pmap_swapin_proc(struct proc *p) -{ - TODO; -} - -void -pmap_swapout_proc(struct proc *p) -{ - TODO; -} - /* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and @@ -1543,25 +1476,19 @@ /* * Allocate object for the kstack. */ - ksobj = td->td_kstack_obj; - if (ksobj == NULL) { - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); - td->td_kstack_obj = ksobj; - } + ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for the kstack for this thread. */ - ks = td->td_kstack; - if (ks == 0) { - ks = kmem_alloc_nofault(kernel_map, - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); - if (ks == 0) - panic("pmap_new_thread: kstack allocation failed"); - TLBIE(ks); - ks += KSTACK_GUARD_PAGES * PAGE_SIZE; - td->td_kstack = ks; - } + ks = kmem_alloc_nofault(kernel_map, + (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + if (ks == 0) + panic("pmap_new_thread: kstack allocation failed"); + TLBIE(ks); + ks += KSTACK_GUARD_PAGES * PAGE_SIZE; + td->td_kstack = ks; for (i = 0; i < KSTACK_PAGES; i++) { /* @@ -1584,12 +1511,6 @@ vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); m->valid = VM_PAGE_BITS_ALL; } -} - -void -pmap_dispose_proc(struct proc *p) -{ - TODO; } void Index: sparc64/sparc64/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/pmap.c,v retrieving revision 1.65 diff -u -r1.65 pmap.c --- sparc64/sparc64/pmap.c 5 Jul 2002 01:27:35 -0000 1.65 +++ sparc64/sparc64/pmap.c 5 Jul 2002 06:10:14 -0000 @@ -812,154 +812,6 @@ } /* - * Create the uarea for a new process. - * This routine directly affects the fork perf for a process. - */ -void -pmap_new_proc(struct proc *p) -{ - vm_page_t ma[UAREA_PAGES]; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - u_int i; - - /* - * Allocate object for the upage. - */ - upobj = p->p_upages_obj; - if (upobj == NULL) { - upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); - p->p_upages_obj = upobj; - } - - /* - * Get a kernel virtual address for the U area for this process. - */ - up = (vm_offset_t)p->p_uarea; - if (up == 0) { - up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); - if (up == 0) - panic("pmap_new_proc: upage allocation failed"); - p->p_uarea = (struct user *)up; - } - - for (i = 0; i < UAREA_PAGES; i++) { - /* - * Get a uarea page. - */ - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - ma[i] = m; - - /* - * Wire the page. - */ - m->wire_count++; - cnt.v_wire_count++; - - vm_page_wakeup(m); - vm_page_flag_clear(m, PG_ZERO); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - m->valid = VM_PAGE_BITS_ALL; - } - - /* - * Enter the pages into the kernel address space. - */ - pmap_qenter(up, ma, UAREA_PAGES); -} - -/* - * Dispose the uarea for a process that has exited. - * This routine directly impacts the exit perf of a process. - */ -void -pmap_dispose_proc(struct proc *p) -{ - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_dispose_proc: upage already missing?"); - vm_page_busy(m); - vm_page_unwire(m, 0); - vm_page_free(m); - } - pmap_qremove(up, UAREA_PAGES); - - /* - * If the process got swapped out some of its UPAGES might have gotten - * swapped. Just get rid of the object to clean up the swap use - * proactively. NOTE! might block waiting for paging I/O to complete. - */ - if (upobj->type == OBJT_SWAP) { - p->p_upages_obj = NULL; - vm_object_deallocate(upobj); - } -} - -/* - * Allow the uarea for a process to be prejudicially paged out. - */ -void -pmap_swapout_proc(struct proc *p) -{ - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_lookup(upobj, i); - if (m == NULL) - panic("pmap_swapout_proc: upage already missing?"); - vm_page_dirty(m); - vm_page_unwire(m, 0); - } - pmap_qremove(up, UAREA_PAGES); -} - -/* - * Bring the uarea for a specified process back in. - */ -void -pmap_swapin_proc(struct proc *p) -{ - vm_page_t ma[UAREA_PAGES]; - vm_object_t upobj; - vm_offset_t up; - vm_page_t m; - int rv; - int i; - - upobj = p->p_upages_obj; - up = (vm_offset_t)p->p_uarea; - for (i = 0; i < UAREA_PAGES; i++) { - m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); - if (m->valid != VM_PAGE_BITS_ALL) { - rv = vm_pager_get_pages(upobj, &m, 1, 0); - if (rv != VM_PAGER_OK) - panic("pmap_swapin_proc: cannot get upage"); - m = vm_page_lookup(upobj, i); - m->valid = VM_PAGE_BITS_ALL; - } - ma[i] = m; - vm_page_wire(m); - vm_page_wakeup(m); - vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); - } - pmap_qenter(up, ma, UAREA_PAGES); -} - -/* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. @@ -1034,7 +886,7 @@ for (i = 0; i < KSTACK_PAGES; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) - panic("pmap_dispose_proc: kstack already missing?"); + panic("pmap_dispose_thread: kstack already missing?"); vm_page_busy(m); vm_page_unwire(m, 0); vm_page_free(m); @@ -1088,7 +940,7 @@ if (m->valid != VM_PAGE_BITS_ALL) { rv = vm_pager_get_pages(ksobj, &m, 1, 0); if (rv != VM_PAGER_OK) - panic("pmap_swapin_proc: cannot get kstack"); + panic("pmap_swapin_thread: cannot get kstack"); m = vm_page_lookup(ksobj, i); m->valid = VM_PAGE_BITS_ALL; } Index: vm/pmap.h =================================================================== RCS file: /home/ncvs/src/sys/vm/pmap.h,v retrieving revision 1.46 diff -u -r1.46 pmap.h --- vm/pmap.h 29 Apr 2002 07:43:16 -0000 1.46 +++ vm/pmap.h 5 Jul 2002 05:51:55 -0000 @@ -128,10 +128,6 @@ void pmap_zero_page_area(vm_page_t, int off, int size); void pmap_prefault(pmap_t, vm_offset_t, vm_map_entry_t); int pmap_mincore(pmap_t pmap, vm_offset_t addr); -void pmap_new_proc(struct proc *p); -void pmap_dispose_proc(struct proc *p); -void pmap_swapout_proc(struct proc *p); -void pmap_swapin_proc(struct proc *p); void pmap_new_thread(struct thread *td); void pmap_dispose_thread(struct thread *td); void pmap_swapout_thread(struct thread *td); Index: vm/vm_extern.h =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_extern.h,v retrieving revision 1.56 diff -u -r1.56 vm_extern.h --- vm/vm_extern.h 5 Apr 2002 00:52:15 -0000 1.56 +++ vm/vm_extern.h 5 Jul 2002 06:01:54 -0000 @@ -95,5 +95,7 @@ void vm_object_print(/* db_expr_t */ long, boolean_t, /* db_expr_t */ long, char *); int vm_fault_quick(caddr_t v, int prot); +void vm_proc_new(struct proc *p); +void vm_proc_dispose(struct proc *p); #endif /* _KERNEL */ #endif /* !_VM_EXTERN_H_ */ Index: vm/vm_glue.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_glue.c,v retrieving revision 1.140 diff -u -r1.140 vm_glue.c --- vm/vm_glue.c 4 Jul 2002 12:37:13 -0000 1.140 +++ vm/vm_glue.c 5 Jul 2002 06:45:56 -0000 @@ -87,8 +87,10 @@ #include #include #include +#include #include #include +#include #include @@ -112,6 +114,8 @@ #ifndef NO_SWAPPING static void swapout(struct proc *); +static void vm_proc_swapin(struct proc *p); +static void vm_proc_swapout(struct proc *p); #endif /* @@ -196,6 +200,144 @@ } /* + * Create the U area for a new process. + * This routine directly affects the fork perf for a process. + */ +void +vm_proc_new(struct proc *p) +{ + vm_page_t ma[UAREA_PAGES]; + vm_object_t upobj; + vm_offset_t up; + vm_page_t m; + u_int i; + + /* + * Allocate object for the upage. + */ + upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES); + p->p_upages_obj = upobj; + + /* + * Get a kernel virtual address for the U area for this process. + */ + up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE); + if (up == 0) + panic("vm_proc_new: upage allocation failed"); + p->p_uarea = (struct user *)up; + + for (i = 0; i < UAREA_PAGES; i++) { + /* + * Get a uarea page. + */ + m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); + ma[i] = m; + + /* + * Wire the page. + */ + m->wire_count++; + cnt.v_wire_count++; + + vm_page_wakeup(m); + vm_page_flag_clear(m, PG_ZERO); + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); + m->valid = VM_PAGE_BITS_ALL; + } + + /* + * Enter the pages into the kernel address space. + */ + pmap_qenter(up, ma, UAREA_PAGES); +} + +/* + * Dispose the U area for a process that has exited. + * This routine directly impacts the exit perf of a process. + * XXX proc_zone is marked UMA_ZONE_NOFREE, so this should never be called. + */ +void +vm_proc_dispose(struct proc *p) +{ + vm_object_t upobj; + vm_offset_t up; + vm_page_t m; + int i; + + upobj = p->p_upages_obj; + up = (vm_offset_t)p->p_uarea; + for (i = 0; i < UAREA_PAGES; i++) { + m = vm_page_lookup(upobj, i); + if (m == NULL) + panic("vm_proc_dispose: upage already missing?"); + vm_page_busy(m); + vm_page_unwire(m, 0); + vm_page_free(m); + } + pmap_qremove(up, UAREA_PAGES); + kmem_free(kernel_map, up, UAREA_PAGES * PAGE_SIZE); + p->p_upages_obj = NULL; + vm_object_deallocate(upobj); +} + +#ifndef NO_SWAPPING +/* + * Allow the U area for a process to be prejudicially paged out. + */ +void +vm_proc_swapout(struct proc *p) +{ + vm_object_t upobj; + vm_offset_t up; + vm_page_t m; + int i; + + upobj = p->p_upages_obj; + up = (vm_offset_t)p->p_uarea; + for (i = 0; i < UAREA_PAGES; i++) { + m = vm_page_lookup(upobj, i); + if (m == NULL) + panic("vm_proc_swapout: upage already missing?"); + vm_page_dirty(m); + vm_page_unwire(m, 0); + } + pmap_qremove(up, UAREA_PAGES); +} + +/* + * Bring the U area for a specified process back in. + */ +void +vm_proc_swapin(struct proc *p) +{ + vm_page_t ma[UAREA_PAGES]; + vm_object_t upobj; + vm_offset_t up; + vm_page_t m; + int rv; + int i; + + upobj = p->p_upages_obj; + up = (vm_offset_t)p->p_uarea; + for (i = 0; i < UAREA_PAGES; i++) { + m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); + if (m->valid != VM_PAGE_BITS_ALL) { + rv = vm_pager_get_pages(upobj, &m, 1, 0); + if (rv != VM_PAGER_OK) + panic("vm_proc_swapin: cannot get upage"); + m = vm_page_lookup(upobj, i); + m->valid = VM_PAGE_BITS_ALL; + } + ma[i] = m; + vm_page_wire(m); + vm_page_wakeup(m); + vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); + } + pmap_qenter(up, ma, UAREA_PAGES); +} +#endif + +/* * Implement fork's actions on an address space. * Here we arrange for the address space to be copied or referenced, * allocate a user struct (pcb and kernel stack), then call the @@ -248,8 +390,6 @@ shmfork(p1, p2); } - pmap_new_proc(p2); - /* XXXKSE this is unsatisfactory but should be adequate */ up = p2->p_uarea; @@ -297,7 +437,6 @@ GIANT_REQUIRED; cpu_wait(p); - pmap_dispose_proc(p); /* drop per-process resources */ /* XXXKSE by here there should not be any threads left! */ FOREACH_THREAD_IN_PROC(p, td) { panic("vm_waitproc: Survivor thread!"); @@ -339,17 +478,22 @@ faultin(p) struct proc *p; { - struct thread *td; - GIANT_REQUIRED; + GIANT_REQUIRED; PROC_LOCK_ASSERT(p, MA_OWNED); mtx_lock_spin(&sched_lock); +#ifdef NO_SWAPPING + if ((p->p_sflag & PS_INMEM) == 0) + panic("faultin: proc swapped out with NO_SWAPPING!"); +#else if ((p->p_sflag & PS_INMEM) == 0) { + struct thread *td; + ++p->p_lock; mtx_unlock_spin(&sched_lock); PROC_UNLOCK(p); - pmap_swapin_proc(p); + vm_proc_swapin(p); FOREACH_THREAD_IN_PROC (p, td) pmap_swapin_thread(td); @@ -364,6 +508,7 @@ /* undo the effect of setting SLOCK above */ --p->p_lock; } +#endif mtx_unlock_spin(&sched_lock); } @@ -641,7 +786,7 @@ remrunqueue(td); /* XXXKSE */ mtx_unlock_spin(&sched_lock); - pmap_swapout_proc(p); + vm_proc_swapout(p); FOREACH_THREAD_IN_PROC(p, td) pmap_swapout_thread(td); mtx_lock_spin(&sched_lock);