summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_glue.c')
-rw-r--r--sys/vm/vm_glue.c104
1 files changed, 30 insertions, 74 deletions
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 4e6db8c..8e09433 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -59,7 +59,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_glue.c,v 1.47 1996/04/09 04:36:58 dyson Exp $
+ * $Id: vm_glue.c,v 1.48 1996/05/02 09:34:51 phk Exp $
*/
#include "opt_ddb.h"
@@ -196,16 +196,15 @@ vm_fork(p1, p2)
register struct proc *p1, *p2;
{
register struct user *up;
- vm_offset_t addr, ptaddr, ptpa;
int error, i;
- vm_map_t map;
pmap_t pvp;
- vm_page_t stkm;
+ vm_object_t upobj;
while ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min) {
VM_WAIT;
}
+#if 0
/*
* avoid copying any of the parent's pagetables or other per-process
* objects that reside in the map by marking all of them
@@ -213,6 +212,7 @@ vm_fork(p1, p2)
*/
(void) vm_map_inherit(&p1->p_vmspace->vm_map,
UPT_MIN_ADDRESS - UPAGES * PAGE_SIZE, VM_MAX_ADDRESS, VM_INHERIT_NONE);
+#endif
p2->p_vmspace = vmspace_fork(p1->p_vmspace);
if (p1->p_vmspace->vm_shm)
@@ -223,61 +223,26 @@ vm_fork(p1, p2)
* process
*/
- addr = (vm_offset_t) kstack;
-
- map = &p2->p_vmspace->vm_map;
pvp = &p2->p_vmspace->vm_pmap;
/*
* allocate object for the upages
*/
- p2->p_vmspace->vm_upages_obj = vm_object_allocate( OBJT_DEFAULT,
+ p2->p_vmspace->vm_upages_obj = upobj = vm_object_allocate( OBJT_DEFAULT,
UPAGES);
- /*
- * put upages into the address space
- */
- error = vm_map_find(map, p2->p_vmspace->vm_upages_obj, 0,
- &addr, UPT_MIN_ADDRESS - addr, FALSE, VM_PROT_ALL,
- VM_PROT_ALL, 0);
- if (error != KERN_SUCCESS)
- panic("vm_fork: vm_map_find (UPAGES) failed, addr=0x%x, error=%d", addr, error);
-
- addr += UPAGES * PAGE_SIZE;
- /* allocate space for page tables */
- error = vm_map_find(map, NULL, 0, &addr, UPT_MAX_ADDRESS - addr, FALSE,
- VM_PROT_ALL, VM_PROT_ALL, 0);
- if (error != KERN_SUCCESS)
- panic("vm_fork: vm_map_find (PTES) failed, addr=0x%x, error=%d", addr, error);
-
/* get a kernel virtual address for the UPAGES for this proc */
up = (struct user *) kmem_alloc_pageable(u_map, UPAGES * PAGE_SIZE);
if (up == NULL)
panic("vm_fork: u_map allocation failed");
- /*
- * create a pagetable page for the UPAGES in the process address space
- */
- ptaddr = trunc_page((u_int) vtopte(kstack));
- (void) vm_fault(map, ptaddr, VM_PROT_READ|VM_PROT_WRITE, FALSE);
- ptpa = pmap_extract(pvp, ptaddr);
- if (ptpa == 0) {
- panic("vm_fork: no pte for UPAGES");
- }
-
- /*
- * hold the page table page for the kernel stack, and fault them in
- */
- stkm = PHYS_TO_VM_PAGE(ptpa);
- vm_page_hold(stkm);
-
for(i=0;i<UPAGES;i++) {
vm_page_t m;
/*
* Get a kernel stack page
*/
- while ((m = vm_page_alloc(p2->p_vmspace->vm_upages_obj,
+ while ((m = vm_page_alloc(upobj,
i, VM_ALLOC_NORMAL)) == NULL) {
VM_WAIT;
}
@@ -286,24 +251,20 @@ vm_fork(p1, p2)
* Wire the page
*/
vm_page_wire(m);
- m->flags &= ~PG_BUSY;
+ PAGE_WAKEUP(m);
/*
* Enter the page into both the kernel and the process
* address space.
*/
pmap_enter( pvp, (vm_offset_t) kstack + i * PAGE_SIZE,
- VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, 1);
+ VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, TRUE);
pmap_kenter(((vm_offset_t) up) + i * PAGE_SIZE,
VM_PAGE_TO_PHYS(m));
m->flags &= ~PG_ZERO;
+ m->flags |= PG_MAPPED;
m->valid = VM_PAGE_BITS_ALL;
}
- /*
- * The page table page for the kernel stack should be held in memory
- * now.
- */
- vm_page_unhold(stkm);
p2->p_addr = up;
@@ -371,33 +332,22 @@ faultin(p)
int s;
if ((p->p_flag & P_INMEM) == 0) {
- vm_map_t map = &p->p_vmspace->vm_map;
pmap_t pmap = &p->p_vmspace->vm_pmap;
vm_page_t stkm, m;
- vm_offset_t ptpa;
int error;
+ vm_object_t upobj = p->p_vmspace->vm_upages_obj;
++p->p_lock;
#if defined(SWAP_DEBUG)
printf("swapping in %d\n", p->p_pid);
#endif
- ptaddr = trunc_page((u_int) vtopte(kstack));
- (void) vm_fault(map, ptaddr, VM_PROT_READ|VM_PROT_WRITE, FALSE);
- ptpa = pmap_extract(&p->p_vmspace->vm_pmap, ptaddr);
- if (ptpa == 0) {
- panic("vm_fork: no pte for UPAGES");
- }
- stkm = PHYS_TO_VM_PAGE(ptpa);
- vm_page_hold(stkm);
-
for(i=0;i<UPAGES;i++) {
int s;
- s = splhigh();
-
+ s = splvm();
retry:
- if ((m = vm_page_lookup(p->p_vmspace->vm_upages_obj, i)) == NULL) {
- if ((m = vm_page_alloc(p->p_vmspace->vm_upages_obj, i, VM_ALLOC_NORMAL)) == NULL) {
+ if ((m = vm_page_lookup(upobj, i)) == NULL) {
+ if ((m = vm_page_alloc(upobj, i, VM_ALLOC_NORMAL)) == NULL) {
VM_WAIT;
goto retry;
}
@@ -407,10 +357,9 @@ retry:
tsleep(m, PVM, "swinuw",0);
goto retry;
}
+ m->flags |= PG_BUSY;
}
vm_page_wire(m);
- if (m->valid == VM_PAGE_BITS_ALL)
- m->flags &= ~PG_BUSY;
splx(s);
pmap_enter( pmap, (vm_offset_t) kstack + i * PAGE_SIZE,
@@ -419,16 +368,15 @@ retry:
VM_PAGE_TO_PHYS(m));
if (m->valid != VM_PAGE_BITS_ALL) {
int rv;
- rv = vm_pager_get_pages(p->p_vmspace->vm_upages_obj,
+ rv = vm_pager_get_pages(upobj,
&m, 1, 0);
if (rv != VM_PAGER_OK)
panic("faultin: cannot get upages for proc: %d\n", p->p_pid);
m->valid = VM_PAGE_BITS_ALL;
- m->flags &= ~PG_BUSY;
}
+ PAGE_WAKEUP(m);
+ m->flags |= PG_MAPPED;
}
- vm_page_unhold(stkm);
-
s = splhigh();
@@ -527,8 +475,12 @@ swapout_procs()
outpri = outpri2 = INT_MIN;
retry:
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
+ struct vmspace *vm;
if (!swappable(p))
continue;
+
+ vm = p->p_vmspace;
+
switch (p->p_stat) {
default:
continue;
@@ -549,22 +501,25 @@ retry:
(p->p_slptime <= 4))
continue;
- vm_map_reference(&p->p_vmspace->vm_map);
+ ++vm->vm_refcnt;
+ vm_map_reference(&vm->vm_map);
/*
* do not swapout a process that is waiting for VM
* datastructures there is a possible deadlock.
*/
- if (!lock_try_write(&p->p_vmspace->vm_map.lock)) {
- vm_map_deallocate(&p->p_vmspace->vm_map);
+ if (!lock_try_write(&vm->vm_map.lock)) {
+ vm_map_deallocate(&vm->vm_map);
+ vmspace_free(vm);
continue;
}
- vm_map_unlock(&p->p_vmspace->vm_map);
+ vm_map_unlock(&vm->vm_map);
/*
* If the process has been asleep for awhile and had
* most of its pages taken away already, swap it out.
*/
swapout(p);
- vm_map_deallocate(&p->p_vmspace->vm_map);
+ vm_map_deallocate(&vm->vm_map);
+ vmspace_free(vm);
didswap++;
goto retry;
}
@@ -612,6 +567,7 @@ swapout(p)
panic("swapout: upage already missing???");
m->dirty = VM_PAGE_BITS_ALL;
vm_page_unwire(m);
+ vm_page_deactivate(m);
pmap_kremove( (vm_offset_t) p->p_addr + PAGE_SIZE * i);
}
pmap_remove(pmap, (vm_offset_t) kstack,
OpenPOWER on IntegriCloud