summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2002-07-07 23:05:27 +0000
committerpeter <peter@FreeBSD.org>2002-07-07 23:05:27 +0000
commitb73c441dad47d23a66fa7545b63e35e625225808 (patch)
tree74cd2868c7e5812fca8fc59540abac90c945c633
parent9c4815fb2170a6fe82ab28145f6a5d1f8741df10 (diff)
downloadFreeBSD-src-b73c441dad47d23a66fa7545b63e35e625225808.zip
FreeBSD-src-b73c441dad47d23a66fa7545b63e35e625225808.tar.gz
Collect all the (now equivalent) pmap_new_proc/pmap_dispose_proc/
pmap_swapin_proc/pmap_swapout_proc functions from the MD pmap code and use a single equivalent MI version. There are other cleanups needed still. While here, use the UMA zone hooks to keep a cache of preinitialized proc structures handy, just like the thread system does. This eliminates one dependency on 'struct proc' being persistent even after being freed. There are some comments about things that can be factored out into ctor/dtor functions if it is worth it. For now they are mostly just doing statistics to get a feel of how it is working.
-rw-r--r--sys/alpha/alpha/pmap.c154
-rw-r--r--sys/amd64/amd64/pmap.c170
-rw-r--r--sys/i386/i386/pmap.c170
-rw-r--r--sys/ia64/ia64/pmap.c148
-rw-r--r--sys/kern/kern_kse.c10
-rw-r--r--sys/kern/kern_proc.c105
-rw-r--r--sys/kern/kern_thread.c10
-rw-r--r--sys/powerpc/aim/mmu_oea.c73
-rw-r--r--sys/powerpc/powerpc/mmu_oea.c73
-rw-r--r--sys/powerpc/powerpc/pmap.c73
-rw-r--r--sys/sparc64/sparc64/pmap.c148
-rw-r--r--sys/vm/pmap.h4
-rw-r--r--sys/vm/vm_extern.h2
-rw-r--r--sys/vm/vm_glue.c159
14 files changed, 277 insertions, 1022 deletions
diff --git a/sys/alpha/alpha/pmap.c b/sys/alpha/alpha/pmap.c
index 9e6ccde..dba9cd8 100644
--- a/sys/alpha/alpha/pmap.c
+++ b/sys/alpha/alpha/pmap.c
@@ -901,160 +901,6 @@ retry:
}
/*
- * 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.
*/
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 7b673e6..9e3c6c3 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -820,176 +820,6 @@ retry:
}
/*
- * 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.
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 7b673e6..9e3c6c3 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -820,176 +820,6 @@ retry:
}
/*
- * 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.
diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c
index 5bf1aeb..1ccac9c 100644
--- a/sys/ia64/ia64/pmap.c
+++ b/sys/ia64/ia64/pmap.c
@@ -707,154 +707,6 @@ pmap_track_modified(vm_offset_t va)
}
/*
- * 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.
*/
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 751dd70..ee7a252 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -97,6 +97,16 @@ thread_ctor(void *mem, int size, void *arg)
(unsigned)RANGEOF(struct thread, td_startzero, td_endzero));
td->td_state = TDS_NEW;
td->td_flags |= TDF_UNBOUND;
+#if 0
+ /*
+ * Maybe move these here from process creation, but maybe not.
+ * Moving them here takes them away from their "natural" place
+ * in the fork process.
+ */
+ /* XXX td_contested does not appear to be initialized for threads! */
+ LIST_INIT(&td->td_contested);
+ callout_init(&td->td_slpcallout, 1);
+#endif
cached_threads--; /* XXXSMP */
active_threads++; /* XXXSMP */
}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 0ddad93..44bf2ce 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -58,6 +58,7 @@
#endif
#include <vm/vm.h>
+#include <vm/vm_extern.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/uma.h>
@@ -76,6 +77,11 @@ static void pgdelete(struct pgrp *);
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 @@ struct mtx pargs_ref_lock;
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,91 @@ procinit()
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, (int)sizeof(struct proc)));
+ p = (struct proc *)mem;
+#if 0
+ /*
+ * Maybe move these from process creation, but maybe not.
+ * Moving them here takes them away from their "natural" place
+ * in the fork process.
+ */
+ 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);
+#endif
+ 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, (int)sizeof(struct proc)));
+ p = (struct proc *)mem;
+ /* INVARIANTS checks go here */
+#if 0 /* See comment in proc_ctor about seperating things */
+ mtx_destroy(&p->p_mtx);
+#endif
+ 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, (int)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, (int)sizeof(struct proc)));
+ p = (struct proc *)mem;
+ vm_proc_dispose(p);
+ cached_procs--;
+ allocated_procs--;
+}
+
/*
* KSE is linked onto the idle queue.
*/
@@ -1143,3 +1235,12 @@ SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD,
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.");
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 751dd70..ee7a252 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -97,6 +97,16 @@ thread_ctor(void *mem, int size, void *arg)
(unsigned)RANGEOF(struct thread, td_startzero, td_endzero));
td->td_state = TDS_NEW;
td->td_flags |= TDF_UNBOUND;
+#if 0
+ /*
+ * Maybe move these here from process creation, but maybe not.
+ * Moving them here takes them away from their "natural" place
+ * in the fork process.
+ */
+ /* XXX td_contested does not appear to be initialized for threads! */
+ LIST_INIT(&td->td_contested);
+ callout_init(&td->td_slpcallout, 1);
+#endif
cached_threads--; /* XXXSMP */
active_threads++; /* XXXSMP */
}
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c
index 691c6f9..817f7f1 100644
--- a/sys/powerpc/aim/mmu_oea.c
+++ b/sys/powerpc/aim/mmu_oea.c
@@ -1170,61 +1170,6 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
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_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
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
@@ -1581,12 +1514,6 @@ pmap_new_thread(struct thread *td)
}
void
-pmap_dispose_proc(struct proc *p)
-{
- TODO;
-}
-
-void
pmap_dispose_thread(struct thread *td)
{
TODO;
diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c
index 691c6f9..817f7f1 100644
--- a/sys/powerpc/powerpc/mmu_oea.c
+++ b/sys/powerpc/powerpc/mmu_oea.c
@@ -1170,61 +1170,6 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
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_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
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
@@ -1581,12 +1514,6 @@ pmap_new_thread(struct thread *td)
}
void
-pmap_dispose_proc(struct proc *p)
-{
- TODO;
-}
-
-void
pmap_dispose_thread(struct thread *td)
{
TODO;
diff --git a/sys/powerpc/powerpc/pmap.c b/sys/powerpc/powerpc/pmap.c
index 691c6f9..817f7f1 100644
--- a/sys/powerpc/powerpc/pmap.c
+++ b/sys/powerpc/powerpc/pmap.c
@@ -1170,61 +1170,6 @@ pmap_mincore(pmap_t pmap, vm_offset_t addr)
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_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva)
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
@@ -1581,12 +1514,6 @@ pmap_new_thread(struct thread *td)
}
void
-pmap_dispose_proc(struct proc *p)
-{
- TODO;
-}
-
-void
pmap_dispose_thread(struct thread *td)
{
TODO;
diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c
index f916ccc..635b4bd 100644
--- a/sys/sparc64/sparc64/pmap.c
+++ b/sys/sparc64/sparc64/pmap.c
@@ -812,154 +812,6 @@ pmap_qremove(vm_offset_t sva, int count)
}
/*
- * 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.
diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h
index e436431..79a73f6 100644
--- a/sys/vm/pmap.h
+++ b/sys/vm/pmap.h
@@ -128,10 +128,6 @@ void pmap_zero_page(vm_page_t);
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);
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index b841329..d646f78 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -95,5 +95,7 @@ void vsunlock(caddr_t, u_int);
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_ */
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 61f78e1..1351c14 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -87,8 +87,10 @@
#include <vm/vm_map.h>
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
+#include <vm/vm_object.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
+#include <vm/vm_pager.h>
#include <sys/user.h>
@@ -112,6 +114,8 @@ SYSINIT(scheduler, SI_SUB_RUN_SCHEDULER, SI_ORDER_FIRST, scheduler, NULL)
#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 @@ vsunlock(addr, len)
}
/*
+ * 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 @@ vm_forkproc(td, p2, td2, flags)
shmfork(p1, p2);
}
- pmap_new_proc(p2);
-
/* XXXKSE this is unsatisfactory but should be adequate */
up = p2->p_uarea;
@@ -297,7 +437,6 @@ vm_waitproc(p)
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 @@ void
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 @@ faultin(p)
/* undo the effect of setting SLOCK above */
--p->p_lock;
}
+#endif
mtx_unlock_spin(&sched_lock);
}
@@ -641,7 +786,7 @@ swapout(p)
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);
OpenPOWER on IntegriCloud