summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/device_pager.c8
-rw-r--r--sys/vm/swap_pager.c44
-rw-r--r--sys/vm/vm_fault.c24
-rw-r--r--sys/vm/vm_glue.c104
-rw-r--r--sys/vm/vm_kern.c29
-rw-r--r--sys/vm/vm_map.c243
-rw-r--r--sys/vm/vm_meter.c10
-rw-r--r--sys/vm/vm_mmap.c5
-rw-r--r--sys/vm/vm_object.c85
-rw-r--r--sys/vm/vm_page.c369
-rw-r--r--sys/vm/vm_pageout.c139
-rw-r--r--sys/vm/vm_pager.c8
12 files changed, 474 insertions, 594 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 8b1ddf2..514b471 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)device_pager.c 8.1 (Berkeley) 6/11/93
- * $Id: device_pager.c,v 1.21 1996/03/09 06:54:41 dyson Exp $
+ * $Id: device_pager.c,v 1.22 1996/05/03 21:01:45 phk Exp $
*/
#include <sys/param.h>
@@ -182,7 +182,7 @@ dev_pager_dealloc(object)
/*
* Free up our fake pages.
*/
- while ((m = object->un_pager.devp.devp_pglist.tqh_first) != 0) {
+ while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) != 0) {
TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, pageq);
dev_pager_putfake(m);
}
@@ -265,14 +265,14 @@ dev_pager_getfake(paddr)
vm_page_t m;
int i;
- if (dev_pager_fakelist.tqh_first == NULL) {
+ if (TAILQ_FIRST(&dev_pager_fakelist) == NULL) {
m = (vm_page_t) malloc(PAGE_SIZE * 2, M_VMPGDATA, M_WAITOK);
for (i = (PAGE_SIZE * 2) / sizeof(*m); i > 0; i--) {
TAILQ_INSERT_TAIL(&dev_pager_fakelist, m, pageq);
m++;
}
}
- m = dev_pager_fakelist.tqh_first;
+ m = TAILQ_FIRST(&dev_pager_fakelist);
TAILQ_REMOVE(&dev_pager_fakelist, m, pageq);
m->flags = PG_BUSY | PG_FICTITIOUS;
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index b6c7db6..4feebd5 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -39,7 +39,7 @@
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
*
* @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
- * $Id: swap_pager.c,v 1.64 1996/05/02 14:21:14 phk Exp $
+ * $Id: swap_pager.c,v 1.65 1996/05/03 21:01:47 phk Exp $
*/
/*
@@ -530,7 +530,7 @@ swap_pager_reclaim()
/* for each pager queue */
for (k = 0; swp_qs[k]; k++) {
- object = swp_qs[k]->tqh_first;
+ object = TAILQ_FIRST(swp_qs[k]);
while (object && (reclaimcount < MAXRECLAIM)) {
/*
@@ -555,7 +555,7 @@ swap_pager_reclaim()
}
}
}
- object = object->pager_object_list.tqe_next;
+ object = TAILQ_NEXT(object, pager_object_list);
}
}
@@ -956,8 +956,8 @@ swap_pager_getpages(object, m, count, reqpage)
spc = NULL; /* we might not use an spc data structure */
- if ((count == 1) && (swap_pager_free.tqh_first != NULL)) {
- spc = swap_pager_free.tqh_first;
+ if ((count == 1) && (TAILQ_FIRST(&swap_pager_free) != NULL)) {
+ spc = TAILQ_FIRST(&swap_pager_free);
TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
kva = spc->spc_kva;
bp = spc->spc_bp;
@@ -1263,9 +1263,9 @@ swap_pager_putpages(object, m, count, sync, rtvals)
/*
* get a swap pager clean data structure, block until we get it
*/
- if (swap_pager_free.tqh_first == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
+ if (TAILQ_FIRST(&swap_pager_free) == NULL ||
+ TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
+ TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
s = splbio();
if (curproc == pageproc) {
retryfree:
@@ -1285,9 +1285,9 @@ retryfree:
*/
if (tsleep(&swap_pager_free, PVM, "swpfre", hz/5)) {
swap_pager_sync();
- if (swap_pager_free.tqh_first == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
+ if (TAILQ_FIRST(&swap_pager_free) == NULL ||
+ TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
+ TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
splx(s);
return VM_PAGER_AGAIN;
}
@@ -1297,17 +1297,17 @@ retryfree:
* the free swap control blocks.
*/
swap_pager_sync();
- if (swap_pager_free.tqh_first == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
+ if (TAILQ_FIRST(&swap_pager_free) == NULL ||
+ TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
+ TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
goto retryfree;
}
}
} else {
pagedaemon_wakeup();
- while (swap_pager_free.tqh_first == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next == NULL ||
- swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
+ while (TAILQ_FIRST(&swap_pager_free) == NULL ||
+ TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list) == NULL ||
+ TAILQ_NEXT(TAILQ_NEXT(TAILQ_FIRST(&swap_pager_free),spc_list),spc_list) == NULL) {
swap_pager_needflags |= SWAP_FREE_NEEDED;
tsleep(&swap_pager_free, PVM, "swpfre", 0);
pagedaemon_wakeup();
@@ -1315,7 +1315,7 @@ retryfree:
}
splx(s);
}
- spc = swap_pager_free.tqh_first;
+ spc = TAILQ_FIRST(&swap_pager_free);
TAILQ_REMOVE(&swap_pager_free, spc, spc_list);
kva = spc->spc_kva;
@@ -1482,7 +1482,7 @@ swap_pager_sync()
register int s;
tspc = NULL;
- if (swap_pager_done.tqh_first == NULL)
+ if (TAILQ_FIRST(&swap_pager_done) == NULL)
return;
for (;;) {
s = splbio();
@@ -1490,7 +1490,7 @@ swap_pager_sync()
* Look up and removal from done list must be done at splbio()
* to avoid conflicts with swap_pager_iodone.
*/
- while ((spc = swap_pager_done.tqh_first) != 0) {
+ while ((spc = TAILQ_FIRST(&swap_pager_done)) != 0) {
pmap_qremove(spc->spc_kva, spc->spc_count);
swap_pager_finish(spc);
TAILQ_REMOVE(&swap_pager_done, spc, spc_list);
@@ -1609,7 +1609,7 @@ swap_pager_iodone(bp)
wakeup(spc->spc_object);
}
if ((swap_pager_needflags & SWAP_FREE_NEEDED) ||
- swap_pager_inuse.tqh_first == 0) {
+ TAILQ_FIRST(&swap_pager_inuse) == 0) {
swap_pager_needflags &= ~SWAP_FREE_NEEDED;
wakeup(&swap_pager_free);
}
@@ -1623,7 +1623,7 @@ swap_pager_iodone(bp)
wakeup(&vm_pageout_pages_needed);
vm_pageout_pages_needed = 0;
}
- if ((swap_pager_inuse.tqh_first == NULL) ||
+ if ((TAILQ_FIRST(&swap_pager_inuse) == NULL) ||
((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min &&
nswiodone + cnt.v_free_count + cnt.v_cache_count >= cnt.v_free_min)) {
pagedaemon_wakeup();
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index e9f8f16..904270b 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_fault.c,v 1.42 1996/03/09 06:48:26 dyson Exp $
+ * $Id: vm_fault.c,v 1.43 1996/03/28 04:53:23 dyson Exp $
*/
/*
@@ -269,8 +269,8 @@ RetryFault:;
int s;
UNLOCK_THINGS;
- s = splhigh();
- if ((m->flags & PG_BUSY) || m->busy) {
+ s = splvm();
+ if (((m->flags & PG_BUSY) || m->busy)) {
m->flags |= PG_WANTED | PG_REFERENCED;
cnt.v_intrans++;
tsleep(m, PSWP, "vmpfw", 0);
@@ -311,7 +311,7 @@ RetryFault:;
* Allocate a new page for this object/offset pair.
*/
m = vm_page_alloc(object, pindex,
- vp?VM_ALLOC_NORMAL:VM_ALLOC_ZERO);
+ (vp || object->backing_object)?VM_ALLOC_NORMAL:VM_ALLOC_ZERO);
if (m == NULL) {
UNLOCK_AND_DEALLOCATE;
@@ -551,9 +551,9 @@ readrest:
vm_pindex_t other_pindex, other_pindex_offset;
vm_page_t tm;
- other_object = object->shadow_head.tqh_first;
+ other_object = TAILQ_FIRST(&object->shadow_head);
if (other_object == first_object)
- other_object = other_object->shadow_list.tqe_next;
+ other_object = TAILQ_NEXT(other_object, shadow_list);
if (!other_object)
panic("vm_fault: other object missing");
if (other_object &&
@@ -712,7 +712,7 @@ readrest:
m->valid = VM_PAGE_BITS_ALL;
pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m), prot, wired);
- if (vp && (change_wiring == 0) && (wired == 0))
+ if ((change_wiring == 0) && (wired == 0))
pmap_prefault(map->pmap, vaddr, entry, first_object);
/*
@@ -780,8 +780,9 @@ vm_fault_wire(map, start, end)
for (va = start; va < end; va += PAGE_SIZE) {
while( curproc != pageproc &&
- (cnt.v_free_count <= cnt.v_pageout_free_min))
+ (cnt.v_free_count <= cnt.v_pageout_free_min)) {
VM_WAIT;
+ }
rv = vm_fault(map, va, VM_PROT_READ|VM_PROT_WRITE, TRUE);
if (rv) {
@@ -817,11 +818,10 @@ vm_fault_unwire(map, start, end)
for (va = start; va < end; va += PAGE_SIZE) {
pa = pmap_extract(pmap, va);
- if (pa == (vm_offset_t) 0) {
- panic("unwire: page not in pmap");
+ if (pa != (vm_offset_t) 0) {
+ pmap_change_wiring(pmap, va, FALSE);
+ vm_page_unwire(PHYS_TO_VM_PAGE(pa));
}
- pmap_change_wiring(pmap, va, FALSE);
- vm_page_unwire(PHYS_TO_VM_PAGE(pa));
}
/*
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,
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index a820f9d..fbad3f1 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_kern.c,v 1.23 1996/04/24 04:16:44 dyson Exp $
+ * $Id: vm_kern.c,v 1.24 1996/05/10 19:28:54 wollman Exp $
*/
/*
@@ -100,6 +100,7 @@ vm_map_t io_map;
vm_map_t clean_map;
vm_map_t phys_map;
vm_map_t exec_map;
+vm_map_t exech_map;
vm_map_t u_map;
/*
@@ -327,22 +328,8 @@ kmem_malloc(map, size, waitflag)
vm_map_insert(map, kmem_object, offset, addr, addr + size,
VM_PROT_ALL, VM_PROT_ALL, 0);
- /*
- * If we can wait, just mark the range as wired (will fault pages as
- * necessary).
- */
- if (waitflag == M_WAITOK) {
- vm_map_unlock(map);
- (void) vm_map_pageable(map, (vm_offset_t) addr, addr + size,
- FALSE);
- vm_map_simplify(map, addr);
- return (addr);
- }
- /*
- * If we cannot wait then we must allocate all memory up front,
- * pulling it off the active queue to prevent pageout.
- */
for (i = 0; i < size; i += PAGE_SIZE) {
+retry:
m = vm_page_alloc(kmem_object, OFF_TO_IDX(offset + i),
(waitflag == M_NOWAIT) ? VM_ALLOC_INTERRUPT : VM_ALLOC_SYSTEM);
@@ -352,6 +339,10 @@ kmem_malloc(map, size, waitflag)
* aren't on any queues.
*/
if (m == NULL) {
+ if (waitflag == M_WAITOK) {
+ VM_WAIT;
+ goto retry;
+ }
while (i != 0) {
i -= PAGE_SIZE;
m = vm_page_lookup(kmem_object,
@@ -362,7 +353,7 @@ kmem_malloc(map, size, waitflag)
vm_map_unlock(map);
return (0);
}
- m->flags &= ~(PG_BUSY|PG_ZERO);
+ m->flags &= ~PG_ZERO;
m->valid = VM_PAGE_BITS_ALL;
}
@@ -386,7 +377,9 @@ kmem_malloc(map, size, waitflag)
for (i = 0; i < size; i += PAGE_SIZE) {
m = vm_page_lookup(kmem_object, OFF_TO_IDX(offset + i));
vm_page_wire(m);
- pmap_kenter(addr + i, VM_PAGE_TO_PHYS(m));
+ PAGE_WAKEUP(m);
+ pmap_enter(kernel_pmap, addr + i, VM_PAGE_TO_PHYS(m),
+ VM_PROT_ALL, 1);
}
vm_map_unlock(map);
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 6195309..e0948e4 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.43 1996/04/29 22:04:57 dyson Exp $
+ * $Id: vm_map.c,v 1.44 1996/05/03 21:01:49 phk Exp $
*/
/*
@@ -157,11 +157,15 @@ static int kentry_count;
static vm_offset_t mapvm_start, mapvm, mapvmmax;
static int mapvmpgcnt;
+static struct vm_map_entry *mappool;
+static int mappoolcnt;
+#define KENTRY_LOW_WATER 128
+
static void _vm_map_clip_end __P((vm_map_t, vm_map_entry_t, vm_offset_t));
static void _vm_map_clip_start __P((vm_map_t, vm_map_entry_t, vm_offset_t));
static vm_map_entry_t vm_map_entry_create __P((vm_map_t));
static void vm_map_entry_delete __P((vm_map_t, vm_map_entry_t));
-static void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t));
+static __inline void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t));
static void vm_map_entry_unwire __P((vm_map_t, vm_map_entry_t));
static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t,
vm_map_entry_t));
@@ -214,11 +218,10 @@ vmspace_alloc(min, max, pageable)
if (mapvmpgcnt == 0 && mapvm == 0) {
int s;
- mapvmpgcnt = btoc(cnt.v_page_count * sizeof(struct vm_map_entry));
- s = splhigh();
- mapvm_start = mapvm = kmem_alloc_pageable(kernel_map, mapvmpgcnt * PAGE_SIZE);
+ mapvmpgcnt = (cnt.v_page_count * sizeof(struct vm_map_entry) + PAGE_SIZE - 1) / PAGE_SIZE;
+ mapvm_start = mapvm = kmem_alloc_pageable(kernel_map,
+ mapvmpgcnt * PAGE_SIZE);
mapvmmax = mapvm_start + mapvmpgcnt * PAGE_SIZE;
- splx(s);
if (!mapvm)
mapvmpgcnt = 0;
}
@@ -241,7 +244,6 @@ vmspace_free(vm)
panic("vmspace_free: attempt to free already freed vmspace");
if (--vm->vm_refcnt == 0) {
- int s, i;
/*
* Lock the map, to wait out all other references to it.
@@ -252,11 +254,17 @@ vmspace_free(vm)
(void) vm_map_delete(&vm->vm_map, vm->vm_map.min_offset,
vm->vm_map.max_offset);
vm_map_unlock(&vm->vm_map);
+
while( vm->vm_map.ref_count != 1)
tsleep(&vm->vm_map.ref_count, PVM, "vmsfre", 0);
--vm->vm_map.ref_count;
+ vm_object_pmap_remove(vm->vm_upages_obj,
+ 0, vm->vm_upages_obj->size);
+ vm_object_deallocate(vm->vm_upages_obj);
pmap_release(&vm->vm_pmap);
FREE(vm, M_VMMAP);
+ } else {
+ wakeup(&vm->vm_map.ref_count);
}
}
@@ -315,44 +323,65 @@ vm_map_init(map, min, max, pageable)
}
/*
+ * vm_map_entry_dispose: [ internal use only ]
+ *
+ * Inverse of vm_map_entry_create.
+ */
+static __inline void
+vm_map_entry_dispose(map, entry)
+ vm_map_t map;
+ vm_map_entry_t entry;
+{
+ int s;
+
+ if (kentry_count < KENTRY_LOW_WATER) {
+ s = splvm();
+ entry->next = kentry_free;
+ kentry_free = entry;
+ ++kentry_count;
+ splx(s);
+ } else {
+ entry->next = mappool;
+ mappool = entry;
+ ++mappoolcnt;
+ }
+}
+
+/*
* vm_map_entry_create: [ internal use only ]
*
* Allocates a VM map entry for insertion.
* No entry fields are filled in. This routine is
*/
-static struct vm_map_entry *mappool;
-static int mappoolcnt;
-
static vm_map_entry_t
vm_map_entry_create(map)
vm_map_t map;
{
vm_map_entry_t entry;
int i;
-
-#define KENTRY_LOW_WATER 64
-#define MAPENTRY_LOW_WATER 128
+ int s;
/*
* This is a *very* nasty (and sort of incomplete) hack!!!!
*/
if (kentry_count < KENTRY_LOW_WATER) {
+ s = splvm();
if (mapvmpgcnt && mapvm) {
vm_page_t m;
m = vm_page_alloc(kernel_object,
- OFF_TO_IDX(mapvm - vm_map_min(kernel_map)),
+ OFF_TO_IDX(mapvm - VM_MIN_KERNEL_ADDRESS),
(map == kmem_map) ? VM_ALLOC_INTERRUPT : VM_ALLOC_NORMAL);
+
if (m) {
int newentries;
newentries = (PAGE_SIZE / sizeof(struct vm_map_entry));
vm_page_wire(m);
- m->flags &= ~PG_BUSY;
+ PAGE_WAKEUP(m);
m->valid = VM_PAGE_BITS_ALL;
- pmap_enter(vm_map_pmap(kmem_map), mapvm,
- VM_PAGE_TO_PHYS(m), VM_PROT_DEFAULT, 1);
- m->flags |= PG_WRITEABLE|PG_MAPPED;
+ pmap_kenter(mapvm, VM_PAGE_TO_PHYS(m));
+ m->flags |= PG_WRITEABLE;
entry = (vm_map_entry_t) mapvm;
mapvm += PAGE_SIZE;
@@ -364,66 +393,34 @@ vm_map_entry_create(map)
}
}
}
+ splx(s);
}
- if (map == kernel_map || map == kmem_map || map == pager_map) {
+ if (map == kernel_map || map == kmem_map || map == pager_map) {
+ s = splvm();
entry = kentry_free;
if (entry) {
kentry_free = entry->next;
--kentry_count;
- return entry;
- }
- entry = mappool;
- if (entry) {
- mappool = entry->next;
- --mappoolcnt;
- return entry;
+ } else {
+ panic("vm_map_entry_create: out of map entries for kernel");
}
+ splx(s);
} else {
entry = mappool;
if (entry) {
mappool = entry->next;
--mappoolcnt;
- return entry;
+ } else {
+ MALLOC(entry, vm_map_entry_t, sizeof(struct vm_map_entry),
+ M_VMMAPENT, M_WAITOK);
}
- MALLOC(entry, vm_map_entry_t, sizeof(struct vm_map_entry),
- M_VMMAPENT, M_WAITOK);
}
- if (entry == NULL)
- panic("vm_map_entry_create: out of map entries");
return (entry);
}
/*
- * vm_map_entry_dispose: [ internal use only ]
- *
- * Inverse of vm_map_entry_create.
- */
-static void
-vm_map_entry_dispose(map, entry)
- vm_map_t map;
- vm_map_entry_t entry;
-{
- if ((kentry_count < KENTRY_LOW_WATER) ||
- ((vm_offset_t) entry >= kentry_data && (vm_offset_t) entry < (kentry_data + kentry_data_size)) ||
- ((vm_offset_t) entry >= mapvm_start && (vm_offset_t) entry < mapvmmax)) {
- entry->next = kentry_free;
- kentry_free = entry;
- ++kentry_count;
- return;
- } else {
- if (mappoolcnt < MAPENTRY_LOW_WATER) {
- entry->next = mappool;
- mappool = entry;
- ++mappoolcnt;
- return;
- }
- FREE(entry, M_VMMAPENT);
- }
-}
-
-/*
* vm_map_entry_{un,}link:
*
* Insert/remove entries from maps.
@@ -637,9 +634,9 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
if ((prev_entry != &map->header) &&
(prev_entry->end == start) &&
+ ((object == NULL) || (prev_entry->object.vm_object == object)) &&
(prev_entry->is_a_map == FALSE) &&
(prev_entry->is_sub_map == FALSE) &&
- ((object == NULL) || (prev_entry->object.vm_object == object)) &&
(prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
(prev_entry->protection == prot) &&
(prev_entry->max_protection == max) &&
@@ -664,13 +661,7 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
prev_entry->end = end;
return (KERN_SUCCESS);
}
- } /* else if ((object == prev_entry->object.vm_object) &&
- (prev_entry->offset + (prev_entry->end - prev_entry->start) == offset)) {
- map->size += (end - prev_entry->end);
- prev_entry->end = end;
- printf("map optim 1\n");
- return (KERN_SUCCESS);
- } */
+ }
}
/*
* Create a new entry
@@ -711,7 +702,6 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
/*
* Update the free space hint
*/
-
if ((map->first_free == prev_entry) &&
(prev_entry->end >= new_entry->start))
map->first_free = new_entry;
@@ -803,7 +793,7 @@ vm_map_find(map, object, offset, addr, length, find_space, prot, max, cow)
start = *addr;
if (map == kmem_map)
- s = splhigh();
+ s = splvm();
vm_map_lock(map);
if (find_space) {
@@ -866,10 +856,13 @@ vm_map_simplify_entry(map, entry)
(prev->wired_count == 0)) {
if (map->first_free == prev)
map->first_free = entry;
+ if (map->hint == prev)
+ map->hint = entry;
vm_map_entry_unlink(map, prev);
entry->start = prev->start;
entry->offset = prev->offset;
- vm_object_deallocate(prev->object.vm_object);
+ if (prev->object.vm_object)
+ vm_object_deallocate(prev->object.vm_object);
vm_map_entry_dispose(map, prev);
}
}
@@ -891,9 +884,12 @@ vm_map_simplify_entry(map, entry)
(next->wired_count == 0)) {
if (map->first_free == next)
map->first_free = entry;
+ if (map->hint == next)
+ map->hint = entry;
vm_map_entry_unlink(map, next);
entry->end = next->end;
- vm_object_deallocate(next->object.vm_object);
+ if (next->object.vm_object)
+ vm_object_deallocate(next->object.vm_object);
vm_map_entry_dispose(map, next);
}
}
@@ -1131,7 +1127,6 @@ vm_map_protect(map, start, end, new_prot, set_max)
*/
if (current->protection != old_prot) {
-
#define MASK(entry) ((entry)->copy_on_write ? ~VM_PROT_WRITE : \
VM_PROT_ALL)
#define max(a,b) ((a) > (b) ? (a) : (b))
@@ -1585,7 +1580,7 @@ vm_map_clean(map, start, end, syncio, invalidate)
* The map in question should be locked.
* [This is the reason for this routine's existence.]
*/
-static void
+static __inline void
vm_map_entry_unwire(map, entry)
vm_map_t map;
register vm_map_entry_t entry;
@@ -1599,7 +1594,7 @@ vm_map_entry_unwire(map, entry)
*
* Deallocate the given entry from the target map.
*/
-static void
+static __inline void
vm_map_entry_delete(map, entry)
register vm_map_t map;
register vm_map_entry_t entry;
@@ -1658,7 +1653,9 @@ vm_map_delete(map, start, end)
* Save the free space hint
*/
- if (map->first_free->start >= start)
+ if (entry == &map->header) {
+ map->first_free = &map->header;
+ } else if (map->first_free->start >= start)
map->first_free = entry->prev;
/*
@@ -1667,14 +1664,16 @@ vm_map_delete(map, start, end)
while ((entry != &map->header) && (entry->start < end)) {
vm_map_entry_t next;
- register vm_offset_t s, e;
- register vm_object_t object;
+ vm_offset_t s, e;
+ vm_object_t object;
+ vm_ooffset_t offset;
vm_map_clip_end(map, entry, end);
next = entry->next;
s = entry->start;
e = entry->end;
+ offset = entry->offset;
/*
* Unwire before removing addresses from the pmap; otherwise,
@@ -1691,15 +1690,16 @@ vm_map_delete(map, start, end)
* which are sharing it.
*/
- if (object == kernel_object || object == kmem_object)
- vm_object_page_remove(object, OFF_TO_IDX(entry->offset),
- OFF_TO_IDX(entry->offset + (e - s)), FALSE);
- else if (!map->is_main_map)
+ if (object == kernel_object || object == kmem_object) {
+ vm_object_page_remove(object, OFF_TO_IDX(offset),
+ OFF_TO_IDX(offset + (e - s)), FALSE);
+ } else if (!map->is_main_map) {
vm_object_pmap_remove(object,
- OFF_TO_IDX(entry->offset),
- OFF_TO_IDX(entry->offset + (e - s)));
- else
+ OFF_TO_IDX(offset),
+ OFF_TO_IDX(offset + (e - s)));
+ } else {
pmap_remove(map->pmap, s, e);
+ }
/*
* Delete the entry (which may delete the object) only after
@@ -1729,7 +1729,7 @@ vm_map_remove(map, start, end)
register int result, s = 0;
if (map == kmem_map)
- s = splhigh();
+ s = splvm();
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
@@ -1806,16 +1806,6 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
if (src_entry->is_sub_map || dst_entry->is_sub_map)
return;
- if (dst_entry->object.vm_object != NULL)
- printf("vm_map_copy_entry: dst_entry object not NULL!\n");
-
- /*
- * If our destination map was wired down, unwire it now.
- */
-
- if (dst_entry->wired_count != 0)
- vm_map_entry_unwire(dst_map, dst_entry);
-
if (src_entry->wired_count == 0) {
boolean_t src_needs_copy;
@@ -1847,35 +1837,28 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
- src_entry->start)));
}
}
+
/*
* Make a copy of the object.
*/
- temp_pindex = OFF_TO_IDX(dst_entry->offset);
- vm_object_copy(src_entry->object.vm_object,
- OFF_TO_IDX(src_entry->offset),
- &dst_entry->object.vm_object,
- &temp_pindex,
- &src_needs_copy);
- dst_entry->offset = IDX_TO_OFF(temp_pindex);
- /*
- * If we didn't get a copy-object now, mark the source map
- * entry so that a shadow will be created to hold its changed
- * pages.
- */
- if (src_needs_copy)
+ if (src_entry->object.vm_object) {
+ if ((src_entry->object.vm_object->handle == NULL) &&
+ (src_entry->object.vm_object->type == OBJT_DEFAULT ||
+ src_entry->object.vm_object->type == OBJT_SWAP))
+ vm_object_collapse(src_entry->object.vm_object);
+ ++src_entry->object.vm_object->ref_count;
+ src_entry->copy_on_write = TRUE;
src_entry->needs_copy = TRUE;
- /*
- * The destination always needs to have a shadow created.
- */
- dst_entry->needs_copy = TRUE;
-
- /*
- * Mark the entries copy-on-write, so that write-enabling the
- * entry won't make copy-on-write pages writable.
- */
- src_entry->copy_on_write = TRUE;
- dst_entry->copy_on_write = TRUE;
+ dst_entry->needs_copy = TRUE;
+ dst_entry->copy_on_write = TRUE;
+ dst_entry->object.vm_object =
+ src_entry->object.vm_object;
+ dst_entry->offset = src_entry->offset;
+ } else {
+ dst_entry->object.vm_object = NULL;
+ dst_entry->offset = 0;
+ }
pmap_copy(dst_map->pmap, src_map->pmap, dst_entry->start,
dst_entry->end - dst_entry->start, src_entry->start);
@@ -1962,7 +1945,6 @@ vmspace_fork(vm1)
/*
* Clone the entry and link into the map.
*/
-
new_entry = vm_map_entry_create(new_map);
*new_entry = *old_entry;
new_entry->wired_count = 0;
@@ -2251,11 +2233,13 @@ vm_map_simplify(map, start)
vm_map_entry_t prev_entry;
vm_map_lock(map);
- if (
- (vm_map_lookup_entry(map, start, &this_entry)) &&
+ if ((vm_map_lookup_entry(map, start, &this_entry)) &&
((prev_entry = this_entry->prev) != &map->header) &&
-
(prev_entry->end == start) &&
+ (prev_entry->object.vm_object == this_entry->object.vm_object) &&
+ ((prev_entry->offset + (prev_entry->end - prev_entry->start))
+ == this_entry->offset) &&
+
(map->is_main_map) &&
(prev_entry->is_a_map == FALSE) &&
@@ -2270,18 +2254,15 @@ vm_map_simplify(map, start)
(prev_entry->wired_count == this_entry->wired_count) &&
(prev_entry->copy_on_write == this_entry->copy_on_write) &&
- (prev_entry->needs_copy == this_entry->needs_copy) &&
-
- (prev_entry->object.vm_object == this_entry->object.vm_object) &&
- ((prev_entry->offset + (prev_entry->end - prev_entry->start))
- == this_entry->offset)
- ) {
+ (prev_entry->needs_copy == this_entry->needs_copy)) {
if (map->first_free == this_entry)
map->first_free = prev_entry;
- SAVE_HINT(map, prev_entry);
+ if (map->hint == this_entry)
+ SAVE_HINT(map, prev_entry);
vm_map_entry_unlink(map, this_entry);
prev_entry->end = this_entry->end;
- vm_object_deallocate(this_entry->object.vm_object);
+ if (this_entry->object.vm_object)
+ vm_object_deallocate(this_entry->object.vm_object);
vm_map_entry_dispose(map, this_entry);
}
vm_map_unlock(map);
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index ade41bc..6481309 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_meter.c 8.4 (Berkeley) 1/4/94
- * $Id: vm_meter.c,v 1.13 1995/12/14 09:55:02 phk Exp $
+ * $Id: vm_meter.c,v 1.14 1996/03/11 06:11:40 hsu Exp $
*/
#include <sys/param.h>
@@ -136,9 +136,9 @@ vmtotal SYSCTL_HANDLER_ARGS
/*
* Mark all objects as inactive.
*/
- for (object = vm_object_list.tqh_first;
+ for (object = TAILQ_FIRST(&vm_object_list);
object != NULL;
- object = object->object_list.tqe_next)
+ object = TAILQ_NEXT(object,object_list))
object->flags &= ~OBJ_ACTIVE;
/*
* Calculate process statistics.
@@ -191,9 +191,9 @@ vmtotal SYSCTL_HANDLER_ARGS
/*
* Calculate object memory usage statistics.
*/
- for (object = vm_object_list.tqh_first;
+ for (object = TAILQ_FIRST(&vm_object_list);
object != NULL;
- object = object->object_list.tqe_next) {
+ object = TAILQ_NEXT(object, object_list)) {
totalp->t_vm += num_pages(object->size);
totalp->t_rm += object->resident_page_count;
if (object->flags & OBJ_ACTIVE) {
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index ede01dc..16f8ebe 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.40 1996/03/16 15:00:05 davidg Exp $
+ * $Id: vm_mmap.c,v 1.41 1996/05/03 21:01:51 phk Exp $
*/
/*
@@ -802,8 +802,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
/*
* "Pre-fault" resident pages.
*/
- if ((map != kernel_map) &&
- (type == OBJT_VNODE) && (map->pmap != NULL)) {
+ if ((type == OBJT_VNODE) && (map->pmap != NULL)) {
pmap_object_init_pt(map->pmap, *addr,
object, (vm_pindex_t) OFF_TO_IDX(foff), size);
}
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 6b180ae..187e777 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.67 1996/03/29 06:28:48 davidg Exp $
+ * $Id: vm_object.c,v 1.68 1996/04/24 04:16:45 dyson Exp $
*/
/*
@@ -278,7 +278,7 @@ vm_object_deallocate(object)
(object->type == OBJT_DEFAULT ||
object->type == OBJT_SWAP)) {
vm_object_t robject;
- robject = object->shadow_head.tqh_first;
+ robject = TAILQ_FIRST(&object->shadow_head);
if ((robject != NULL) &&
(robject->handle == NULL) &&
(robject->type == OBJT_DEFAULT ||
@@ -288,7 +288,7 @@ vm_object_deallocate(object)
object->ref_count += 2;
do {
- s = splhigh();
+ s = splvm();
while (robject->paging_in_progress) {
robject->flags |= OBJ_PIPWNT;
tsleep(robject, PVM, "objde1", 0);
@@ -375,7 +375,7 @@ vm_object_terminate(object)
/*
* wait for the pageout daemon to be done with the object
*/
- s = splhigh();
+ s = splvm();
while (object->paging_in_progress) {
object->flags |= OBJ_PIPWNT;
tsleep(object, PVM, "objtrm", 0);
@@ -402,9 +402,10 @@ vm_object_terminate(object)
* Now free the pages. For internal objects, this also removes them
* from paging queues.
*/
- while ((p = object->memq.tqh_first) != NULL) {
+ while ((p = TAILQ_FIRST(&object->memq)) != NULL) {
if (p->flags & PG_BUSY)
printf("vm_object_terminate: freeing busy page\n");
+ vm_page_protect(p, VM_PROT_NONE);
PAGE_WAKEUP(p);
vm_page_free(p);
cnt.v_pfree++;
@@ -478,12 +479,12 @@ vm_object_page_clean(object, start, end, syncio, lockflag)
if ((tstart == 0) && (tend == object->size)) {
object->flags &= ~(OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY);
}
- for(p = object->memq.tqh_first; p; p = p->listq.tqe_next)
+ for(p = TAILQ_FIRST(&object->memq); p; p = TAILQ_NEXT(p, listq))
p->flags |= PG_CLEANCHK;
rescan:
- for(p = object->memq.tqh_first; p; p = np) {
- np = p->listq.tqe_next;
+ for(p = TAILQ_FIRST(&object->memq); p; p = np) {
+ np = TAILQ_NEXT(p, listq);
pi = p->pindex;
if (((p->flags & PG_CLEANCHK) == 0) ||
@@ -499,7 +500,7 @@ rescan:
continue;
}
- s = splhigh();
+ s = splvm();
if ((p->flags & PG_BUSY) || p->busy) {
p->flags |= PG_WANTED|PG_REFERENCED;
tsleep(p, PVM, "vpcwai", 0);
@@ -597,8 +598,8 @@ vm_object_deactivate_pages(object)
{
register vm_page_t p, next;
- for (p = object->memq.tqh_first; p != NULL; p = next) {
- next = p->listq.tqe_next;
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
+ next = TAILQ_NEXT(p, listq);
vm_page_deactivate(p);
}
}
@@ -613,7 +614,7 @@ vm_object_cache_trim()
register vm_object_t object;
while (vm_object_cached > vm_object_cache_max) {
- object = vm_object_cached_list.tqh_first;
+ object = TAILQ_FIRST(&vm_object_cached_list);
vm_object_reference(object);
pager_cache(object, FALSE);
@@ -641,7 +642,7 @@ vm_object_pmap_copy(object, start, end)
if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0)
return;
- for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) {
vm_page_protect(p, VM_PROT_READ);
}
@@ -665,7 +666,7 @@ vm_object_pmap_remove(object, start, end)
register vm_page_t p;
if (object == NULL)
return;
- for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) {
if (p->pindex >= start && p->pindex < end)
vm_page_protect(p, VM_PROT_NONE);
}
@@ -808,17 +809,16 @@ vm_object_qcollapse(object)
backing_object_paging_offset_index = OFF_TO_IDX(backing_object->paging_offset);
paging_offset_index = OFF_TO_IDX(object->paging_offset);
size = object->size;
- p = backing_object->memq.tqh_first;
+ p = TAILQ_FIRST(&backing_object->memq);
while (p) {
vm_page_t next;
- next = p->listq.tqe_next;
+ next = TAILQ_NEXT(p, listq);
if ((p->flags & (PG_BUSY | PG_FICTITIOUS)) ||
(p->queue == PQ_CACHE) || !p->valid || p->hold_count || p->wire_count || p->busy) {
p = next;
continue;
}
- vm_page_protect(p, VM_PROT_NONE);
new_pindex = p->pindex - backing_offset_index;
if (p->pindex < backing_offset_index ||
new_pindex >= size) {
@@ -826,6 +826,7 @@ vm_object_qcollapse(object)
swap_pager_freespace(backing_object,
backing_object_paging_offset_index+p->pindex,
1);
+ vm_page_protect(p, VM_PROT_NONE);
vm_page_free(p);
} else {
pp = vm_page_lookup(object, new_pindex);
@@ -834,6 +835,7 @@ vm_object_qcollapse(object)
if (backing_object->type == OBJT_SWAP)
swap_pager_freespace(backing_object,
backing_object_paging_offset_index + p->pindex, 1);
+ vm_page_protect(p, VM_PROT_NONE);
vm_page_free(p);
} else {
if (backing_object->type == OBJT_SWAP)
@@ -930,7 +932,7 @@ vm_object_collapse(object)
* shadow them.
*/
- while ((p = backing_object->memq.tqh_first) != 0) {
+ while ((p = TAILQ_FIRST(&backing_object->memq)) != 0) {
new_pindex = p->pindex - backing_offset_index;
@@ -1071,7 +1073,7 @@ vm_object_collapse(object)
* here.
*/
- for (p = backing_object->memq.tqh_first; p; p = p->listq.tqe_next) {
+ for (p = TAILQ_FIRST(&backing_object->memq); p; p = TAILQ_NEXT(p, listq)) {
new_pindex = p->pindex - backing_offset_index;
/*
@@ -1160,24 +1162,29 @@ vm_object_page_remove(object, start, end, clean_only)
again:
size = end - start;
if (size > 4 || size >= object->size / 4) {
- for (p = object->memq.tqh_first; p != NULL; p = next) {
- next = p->listq.tqe_next;
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
+ next = TAILQ_NEXT(p, listq);
if ((start <= p->pindex) && (p->pindex < end)) {
-
if (p->wire_count != 0) {
vm_page_protect(p, VM_PROT_NONE);
p->valid = 0;
continue;
}
- s = splhigh();
+ /*
+ * The busy flags are only cleared at
+ * interrupt -- minimize the spl transitions
+ */
if ((p->flags & PG_BUSY) || p->busy) {
- p->flags |= PG_WANTED;
- tsleep(p, PVM, "vmopar", 0);
+ s = splvm();
+ if ((p->flags & PG_BUSY) || p->busy) {
+ p->flags |= PG_WANTED;
+ tsleep(p, PVM, "vmopar", 0);
+ splx(s);
+ goto again;
+ }
splx(s);
- goto again;
}
- splx(s);
if (clean_only) {
vm_page_test_dirty(p);
@@ -1199,14 +1206,20 @@ again:
size -= 1;
continue;
}
- s = splhigh();
+ /*
+ * The busy flags are only cleared at
+ * interrupt -- minimize the spl transitions
+ */
if ((p->flags & PG_BUSY) || p->busy) {
- p->flags |= PG_WANTED;
- tsleep(p, PVM, "vmopar", 0);
+ s = splvm();
+ if ((p->flags & PG_BUSY) || p->busy) {
+ p->flags |= PG_WANTED;
+ tsleep(p, PVM, "vmopar", 0);
+ splx(s);
+ goto again;
+ }
splx(s);
- goto again;
}
- splx(s);
if (clean_only) {
vm_page_test_dirty(p);
if (p->valid & p->dirty) {
@@ -1391,9 +1404,9 @@ DDB_vm_object_check()
* make sure that internal objs are in a map somewhere
* and none have zero ref counts.
*/
- for (object = vm_object_list.tqh_first;
+ for (object = TAILQ_FIRST(&vm_object_list);
object != NULL;
- object = object->object_list.tqe_next) {
+ object = TAILQ_NEXT(object, object_list)) {
if (object->handle == NULL &&
(object->type == OBJT_DEFAULT || object->type == OBJT_SWAP)) {
if (object->ref_count == 0) {
@@ -1436,14 +1449,14 @@ vm_object_print(iobject, full, dummy3, dummy4)
(int) object->paging_offset,
(int) object->backing_object, (int) object->backing_object_offset);
printf("cache: next=%p, prev=%p\n",
- object->cached_list.tqe_next, object->cached_list.tqe_prev);
+ TAILQ_NEXT(object, cached_list), TAILQ_PREV(object, cached_list));
if (!full)
return;
indent += 2;
count = 0;
- for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
+ for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) {
if (count == 0)
iprintf("memory:=");
else if (count == 6) {
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 6f10cea..7a95941 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- * $Id: vm_page.c,v 1.49 1996/03/09 06:56:39 dyson Exp $
+ * $Id: vm_page.c,v 1.50 1996/03/28 04:53:27 dyson Exp $
*/
/*
@@ -140,7 +140,6 @@ static u_short vm_page_dev_bsize_chunks[] = {
static inline __pure int
vm_page_hash __P((vm_object_t object, vm_pindex_t pindex))
__pure2;
-static void vm_page_unqueue __P((vm_page_t ));
/*
* vm_set_page_size:
@@ -244,7 +243,7 @@ vm_page_startup(starta, enda, vaddr)
vm_page_buckets = (struct pglist *) vaddr;
bucket = vm_page_buckets;
if (vm_page_bucket_count == 0) {
- vm_page_bucket_count = 2;
+ vm_page_bucket_count = 1;
while (vm_page_bucket_count < atop(total))
vm_page_bucket_count <<= 1;
}
@@ -383,7 +382,7 @@ vm_page_hash(object, pindex)
* The object and page must be locked, and must be splhigh.
*/
-inline void
+__inline void
vm_page_insert(m, object, pindex)
register vm_page_t m;
register vm_object_t object;
@@ -432,7 +431,7 @@ vm_page_insert(m, object, pindex)
* The object and page must be locked, and at splhigh.
*/
-inline void
+__inline void
vm_page_remove(m)
register vm_page_t m;
{
@@ -487,14 +486,13 @@ vm_page_lookup(object, pindex)
bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
- s = splhigh();
- for (m = bucket->tqh_first; m != NULL; m = m->hashq.tqe_next) {
+ s = splvm();
+ for (m = TAILQ_FIRST(bucket); m != NULL; m = TAILQ_NEXT(m,hashq)) {
if ((m->object == object) && (m->pindex == pindex)) {
splx(s);
return (m);
}
}
-
splx(s);
return (NULL);
}
@@ -515,7 +513,7 @@ vm_page_rename(m, new_object, new_pindex)
{
int s;
- s = splhigh();
+ s = splvm();
vm_page_remove(m);
vm_page_insert(m, new_object, new_pindex);
splx(s);
@@ -524,7 +522,7 @@ vm_page_rename(m, new_object, new_pindex)
/*
* vm_page_unqueue must be called at splhigh();
*/
-static inline void
+__inline void
vm_page_unqueue(vm_page_t m)
{
int queue = m->queue;
@@ -575,19 +573,19 @@ vm_page_alloc(object, pindex, page_req)
page_req = VM_ALLOC_SYSTEM;
};
- s = splhigh();
+ s = splvm();
switch (page_req) {
case VM_ALLOC_NORMAL:
if (cnt.v_free_count >= cnt.v_free_reserved) {
- m = vm_page_queue_free.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_free);
if (m == NULL) {
--vm_page_zero_count;
- m = vm_page_queue_zero.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_zero);
}
} else {
- m = vm_page_queue_cache.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_cache);
if (m == NULL) {
splx(s);
pagedaemon_wakeup();
@@ -598,14 +596,14 @@ vm_page_alloc(object, pindex, page_req)
case VM_ALLOC_ZERO:
if (cnt.v_free_count >= cnt.v_free_reserved) {
- m = vm_page_queue_zero.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_zero);
if (m) {
--vm_page_zero_count;
} else {
- m = vm_page_queue_free.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_free);
}
} else {
- m = vm_page_queue_cache.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_cache);
if (m == NULL) {
splx(s);
pagedaemon_wakeup();
@@ -618,13 +616,13 @@ vm_page_alloc(object, pindex, page_req)
if ((cnt.v_free_count >= cnt.v_free_reserved) ||
((cnt.v_cache_count == 0) &&
(cnt.v_free_count >= cnt.v_interrupt_free_min))) {
- m = vm_page_queue_free.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_free);
if (m == NULL) {
--vm_page_zero_count;
- m = vm_page_queue_zero.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_zero);
}
} else {
- m = vm_page_queue_cache.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_cache);
if (m == NULL) {
splx(s);
pagedaemon_wakeup();
@@ -635,10 +633,10 @@ vm_page_alloc(object, pindex, page_req)
case VM_ALLOC_INTERRUPT:
if (cnt.v_free_count > 0) {
- m = vm_page_queue_free.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_free);
if (m == NULL) {
--vm_page_zero_count;
- m = vm_page_queue_zero.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_zero);
}
} else {
splx(s);
@@ -663,8 +661,8 @@ vm_page_alloc(object, pindex, page_req)
m->flags = PG_BUSY;
}
m->wire_count = 0;
- m->hold_count = 0;
m->act_count = 0;
+ m->hold_count = 0;
m->busy = 0;
m->valid = 0;
m->dirty = 0;
@@ -688,114 +686,35 @@ vm_page_alloc(object, pindex, page_req)
}
/*
- * This interface is for merging with malloc() someday.
- * Even if we never implement compaction so that contiguous allocation
- * works after initialization time, malloc()'s data structures are good
- * for statistics and for allocations of less than a page.
+ * vm_page_activate:
+ *
+ * Put the specified page on the active list (if appropriate).
+ *
+ * The page queues must be locked.
*/
-void *
-contigmalloc(size, type, flags, low, high, alignment, boundary)
- unsigned long size; /* should be size_t here and for malloc() */
- int type;
- int flags;
- unsigned long low;
- unsigned long high;
- unsigned long alignment;
- unsigned long boundary;
+void
+vm_page_activate(m)
+ register vm_page_t m;
{
- int i, s, start;
- vm_offset_t addr, phys, tmp_addr;
- vm_page_t pga = vm_page_array;
-
- size = round_page(size);
- if (size == 0)
- panic("vm_page_alloc_contig: size must not be 0");
- if ((alignment & (alignment - 1)) != 0)
- panic("vm_page_alloc_contig: alignment must be a power of 2");
- if ((boundary & (boundary - 1)) != 0)
- panic("vm_page_alloc_contig: boundary must be a power of 2");
-
- start = 0;
- s = splhigh();
-again:
- /*
- * Find first page in array that is free, within range, aligned, and
- * such that the boundary won't be crossed.
- */
- for (i = start; i < cnt.v_page_count; i++) {
- phys = VM_PAGE_TO_PHYS(&pga[i]);
- if ((pga[i].queue == PQ_FREE) &&
- (phys >= low) && (phys < high) &&
- ((phys & (alignment - 1)) == 0) &&
- (((phys ^ (phys + size - 1)) & ~(boundary - 1)) == 0))
- break;
- }
-
- /*
- * If the above failed or we will exceed the upper bound, fail.
- */
- if ((i == cnt.v_page_count) ||
- ((VM_PAGE_TO_PHYS(&pga[i]) + size) > high)) {
- splx(s);
- return (NULL);
- }
- start = i;
+ int s;
- /*
- * Check successive pages for contiguous and free.
- */
- for (i = start + 1; i < (start + size / PAGE_SIZE); i++) {
- if ((VM_PAGE_TO_PHYS(&pga[i]) !=
- (VM_PAGE_TO_PHYS(&pga[i - 1]) + PAGE_SIZE)) ||
- (pga[i].queue != PQ_FREE)) {
- start++;
- goto again;
- }
- }
+ s = splvm();
+ if (m->queue == PQ_ACTIVE)
+ panic("vm_page_activate: already active");
- /*
- * We've found a contiguous chunk that meets are requirements.
- * Allocate kernel VM, unfree and assign the physical pages to it and
- * return kernel VM pointer.
- */
- tmp_addr = addr = kmem_alloc_pageable(kernel_map, size);
- if (addr == 0) {
- splx(s);
- return (NULL);
- }
+ if (m->queue == PQ_CACHE)
+ cnt.v_reactivated++;
- for (i = start; i < (start + size / PAGE_SIZE); i++) {
- vm_page_t m = &pga[i];
+ vm_page_unqueue(m);
- TAILQ_REMOVE(&vm_page_queue_free, m, pageq);
- cnt.v_free_count--;
- m->valid = VM_PAGE_BITS_ALL;
- m->flags = 0;
- m->dirty = 0;
- m->wire_count = 0;
- m->act_count = 0;
- m->busy = 0;
- m->queue = PQ_NONE;
- vm_page_insert(m, kernel_object,
- OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS));
- vm_page_wire(m);
- pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
- tmp_addr += PAGE_SIZE;
+ if (m->wire_count == 0) {
+ if (m->act_count < 5)
+ m->act_count = 5;
+ TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
+ m->queue = PQ_ACTIVE;
+ cnt.v_active_count++;
}
-
splx(s);
- return ((void *)addr);
-}
-
-vm_offset_t
-vm_page_alloc_contig(size, low, high, alignment)
- vm_offset_t size;
- vm_offset_t low;
- vm_offset_t high;
- vm_offset_t alignment;
-{
- return ((vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, low, high,
- alignment, 0ul));
}
/*
@@ -813,7 +732,7 @@ vm_page_free(m)
int s;
int flags = m->flags;
- s = splhigh();
+ s = splvm();
if (m->busy || (flags & PG_BUSY) || (m->queue == PQ_FREE)) {
printf("vm_page_free: pindex(%ld), busy(%d), PG_BUSY(%d)\n",
m->pindex, m->busy, (flags & PG_BUSY) ? 1 : 0);
@@ -824,7 +743,8 @@ vm_page_free(m)
}
if (m->hold_count) {
- panic("freeing held page, count=%d", m->hold_count);
+ panic("freeing held page, count=%d, pindex=%d(0x%x)",
+ m->hold_count, m->pindex, m->pindex);
}
vm_page_remove(m);
@@ -840,7 +760,19 @@ vm_page_free(m)
m->wire_count = 0;
}
m->queue = PQ_FREE;
- TAILQ_INSERT_TAIL(&vm_page_queue_free, m, pageq);
+
+ /*
+ * If the pageout process is grabbing the page, it is likely
+ * that the page is NOT in the cache. It is more likely that
+ * the page will be partially in the cache if it is being
+ * explicitly freed.
+ */
+ if (curproc == pageproc) {
+ TAILQ_INSERT_TAIL(&vm_page_queue_free, m, pageq);
+ } else {
+ TAILQ_INSERT_HEAD(&vm_page_queue_free, m, pageq);
+ }
+
splx(s);
/*
* if pageout daemon needs pages, then tell it that there are
@@ -859,7 +791,6 @@ vm_page_free(m)
*/
if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) {
wakeup(&cnt.v_free_count);
- wakeup(&proc0);
}
} else {
splx(s);
@@ -884,7 +815,7 @@ vm_page_wire(m)
int s;
if (m->wire_count == 0) {
- s = splhigh();
+ s = splvm();
vm_page_unqueue(m);
splx(s);
cnt.v_wire_count++;
@@ -907,7 +838,7 @@ vm_page_unwire(m)
{
int s;
- s = splhigh();
+ s = splvm();
if (m->wire_count > 0)
m->wire_count--;
@@ -916,47 +847,14 @@ vm_page_unwire(m)
cnt.v_wire_count--;
TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
m->queue = PQ_ACTIVE;
- if( m->act_count < ACT_MAX)
- m->act_count += 1;
- cnt.v_active_count++;
- }
- splx(s);
-}
-
-/*
- * vm_page_activate:
- *
- * Put the specified page on the active list (if appropriate).
- *
- * The page queues must be locked.
- */
-void
-vm_page_activate(m)
- register vm_page_t m;
-{
- int s;
-
- s = splhigh();
- if (m->queue == PQ_ACTIVE)
- panic("vm_page_activate: already active");
-
- if (m->queue == PQ_CACHE)
- cnt.v_reactivated++;
-
- vm_page_unqueue(m);
-
- if (m->wire_count == 0) {
- TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
- m->queue = PQ_ACTIVE;
if (m->act_count < 5)
m->act_count = 5;
- else if( m->act_count < ACT_MAX)
- m->act_count += 1;
cnt.v_active_count++;
}
splx(s);
}
+
/*
* vm_page_deactivate:
*
@@ -982,7 +880,7 @@ vm_page_deactivate(m)
if (m->queue == PQ_INACTIVE)
return;
- spl = splhigh();
+ spl = splvm();
if (m->wire_count == 0 && m->hold_count == 0) {
if (m->queue == PQ_CACHE)
cnt.v_reactivated++;
@@ -990,7 +888,6 @@ vm_page_deactivate(m)
TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
m->queue = PQ_INACTIVE;
cnt.v_inactive_count++;
- m->act_count = 0;
}
splx(spl);
}
@@ -1014,7 +911,7 @@ vm_page_cache(m)
return;
vm_page_protect(m, VM_PROT_NONE);
- s = splhigh();
+ s = splvm();
vm_page_unqueue(m);
TAILQ_INSERT_TAIL(&vm_page_queue_cache, m, pageq);
m->queue = PQ_CACHE;
@@ -1030,35 +927,6 @@ vm_page_cache(m)
splx(s);
}
-/*
- * vm_page_zero_fill:
- *
- * Zero-fill the specified page.
- * Written as a standard pagein routine, to
- * be used by the zero-fill object.
- */
-boolean_t
-vm_page_zero_fill(m)
- vm_page_t m;
-{
- pmap_zero_page(VM_PAGE_TO_PHYS(m));
- return (TRUE);
-}
-
-/*
- * vm_page_copy:
- *
- * Copy one page to another
- */
-void
-vm_page_copy(src_m, dest_m)
- vm_page_t src_m;
- vm_page_t dest_m;
-{
- pmap_copy_page(VM_PAGE_TO_PHYS(src_m), VM_PAGE_TO_PHYS(dest_m));
- dest_m->valid = VM_PAGE_BITS_ALL;
-}
-
/*
* mapping function for valid bits or for dirty bits in
@@ -1126,8 +994,6 @@ vm_page_is_valid(m, base, size)
return 0;
}
-
-
void
vm_page_test_dirty(m)
vm_page_t m;
@@ -1138,6 +1004,115 @@ vm_page_test_dirty(m)
}
}
+/*
+ * This interface is for merging with malloc() someday.
+ * Even if we never implement compaction so that contiguous allocation
+ * works after initialization time, malloc()'s data structures are good
+ * for statistics and for allocations of less than a page.
+ */
+void *
+contigmalloc(size, type, flags, low, high, alignment, boundary)
+ unsigned long size; /* should be size_t here and for malloc() */
+ int type;
+ int flags;
+ unsigned long low;
+ unsigned long high;
+ unsigned long alignment;
+ unsigned long boundary;
+{
+ int i, s, start;
+ vm_offset_t addr, phys, tmp_addr;
+ vm_page_t pga = vm_page_array;
+
+ size = round_page(size);
+ if (size == 0)
+ panic("vm_page_alloc_contig: size must not be 0");
+ if ((alignment & (alignment - 1)) != 0)
+ panic("vm_page_alloc_contig: alignment must be a power of 2");
+ if ((boundary & (boundary - 1)) != 0)
+ panic("vm_page_alloc_contig: boundary must be a power of 2");
+
+ start = 0;
+ s = splvm();
+again:
+ /*
+ * Find first page in array that is free, within range, aligned, and
+ * such that the boundary won't be crossed.
+ */
+ for (i = start; i < cnt.v_page_count; i++) {
+ phys = VM_PAGE_TO_PHYS(&pga[i]);
+ if ((pga[i].queue == PQ_FREE) &&
+ (phys >= low) && (phys < high) &&
+ ((phys & (alignment - 1)) == 0) &&
+ (((phys ^ (phys + size - 1)) & ~(boundary - 1)) == 0))
+ break;
+ }
+
+ /*
+ * If the above failed or we will exceed the upper bound, fail.
+ */
+ if ((i == cnt.v_page_count) ||
+ ((VM_PAGE_TO_PHYS(&pga[i]) + size) > high)) {
+ splx(s);
+ return (NULL);
+ }
+ start = i;
+
+ /*
+ * Check successive pages for contiguous and free.
+ */
+ for (i = start + 1; i < (start + size / PAGE_SIZE); i++) {
+ if ((VM_PAGE_TO_PHYS(&pga[i]) !=
+ (VM_PAGE_TO_PHYS(&pga[i - 1]) + PAGE_SIZE)) ||
+ (pga[i].queue != PQ_FREE)) {
+ start++;
+ goto again;
+ }
+ }
+
+ /*
+ * We've found a contiguous chunk that meets are requirements.
+ * Allocate kernel VM, unfree and assign the physical pages to it and
+ * return kernel VM pointer.
+ */
+ tmp_addr = addr = kmem_alloc_pageable(kernel_map, size);
+ if (addr == 0) {
+ splx(s);
+ return (NULL);
+ }
+
+ for (i = start; i < (start + size / PAGE_SIZE); i++) {
+ vm_page_t m = &pga[i];
+
+ TAILQ_REMOVE(&vm_page_queue_free, m, pageq);
+ cnt.v_free_count--;
+ m->valid = VM_PAGE_BITS_ALL;
+ m->flags = 0;
+ m->dirty = 0;
+ m->wire_count = 0;
+ m->busy = 0;
+ m->queue = PQ_NONE;
+ vm_page_insert(m, kernel_object,
+ OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS));
+ vm_page_wire(m);
+ pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
+ tmp_addr += PAGE_SIZE;
+ }
+
+ splx(s);
+ return ((void *)addr);
+}
+
+vm_offset_t
+vm_page_alloc_contig(size, low, high, alignment)
+ vm_offset_t size;
+ vm_offset_t low;
+ vm_offset_t high;
+ vm_offset_t alignment;
+{
+ return ((vm_offset_t)contigmalloc(size, M_DEVBUF, M_NOWAIT, low, high,
+ alignment, 0ul));
+}
#ifdef DDB
void
DDB_print_page_info(void)
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index e10c106..950ebe1 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -65,7 +65,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.c,v 1.69 1996/03/28 04:53:28 dyson Exp $
+ * $Id: vm_pageout.c,v 1.70 1996/04/11 21:05:25 bde Exp $
*/
/*
@@ -138,8 +138,6 @@ extern int nswiodone;
extern int vm_swap_size;
extern int vfs_update_wakeup;
-#define MAXSCAN 1024 /* maximum number of pages to scan in queues */
-
#define MAXLAUNDER (cnt.v_page_count > 1800 ? 32 : 16)
#define VM_PAGEOUT_PAGE_COUNT 16
@@ -415,9 +413,9 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
* scan the objects entire memory queue
*/
rcount = object->resident_page_count;
- p = object->memq.tqh_first;
+ p = TAILQ_FIRST(&object->memq);
while (p && (rcount-- > 0)) {
- next = p->listq.tqe_next;
+ next = TAILQ_NEXT(p, listq);
cnt.v_pdpages++;
if (p->wire_count != 0 ||
p->hold_count != 0 ||
@@ -434,26 +432,9 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
if (p->queue == PQ_ACTIVE) {
if (!pmap_is_referenced(VM_PAGE_TO_PHYS(p)) &&
(p->flags & PG_REFERENCED) == 0) {
- p->act_count -= min(p->act_count, ACT_DECLINE);
- /*
- * if the page act_count is zero -- then we
- * deactivate
- */
- if (!p->act_count) {
- if (!map_remove_only)
- vm_page_deactivate(p);
- vm_page_protect(p, VM_PROT_NONE);
- /*
- * else if on the next go-around we
- * will deactivate the page we need to
- * place the page on the end of the
- * queue to age the other pages in
- * memory.
- */
- } else {
- TAILQ_REMOVE(&vm_page_queue_active, p, pageq);
- TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq);
- }
+ vm_page_protect(p, VM_PROT_NONE);
+ if (!map_remove_only)
+ vm_page_deactivate(p);
/*
* see if we are done yet
*/
@@ -471,8 +452,6 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
*/
pmap_clear_reference(VM_PAGE_TO_PHYS(p));
p->flags &= ~PG_REFERENCED;
- if (p->act_count < ACT_MAX)
- p->act_count += ACT_ADVANCE;
TAILQ_REMOVE(&vm_page_queue_active, p, pageq);
TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq);
@@ -544,9 +523,12 @@ vm_pageout_scan()
vm_object_t object;
int force_wakeup = 0;
int vnodes_skipped = 0;
+ int usagefloor;
+ int i;
pages_freed = 0;
+
/*
* Start scanning the inactive queue for pages we can free. We keep
* scanning until we have enough free pages or we have scanned through
@@ -559,13 +541,14 @@ vm_pageout_scan()
rescan1:
maxscan = cnt.v_inactive_count;
- m = vm_page_queue_inactive.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_inactive);
while ((m != NULL) && (maxscan-- > 0) &&
- ((cnt.v_cache_count + cnt.v_free_count) < (cnt.v_cache_min + cnt.v_free_target))) {
+ ((cnt.v_cache_count + cnt.v_free_count) <
+ (cnt.v_cache_min + cnt.v_free_target))) {
vm_page_t next;
cnt.v_pdpages++;
- next = m->pageq.tqe_next;
+ next = TAILQ_NEXT(m, pageq);
#if defined(VM_DIAGNOSE)
if (m->queue != PQ_INACTIVE) {
@@ -575,7 +558,8 @@ rescan1:
#endif
/*
- * dont mess with busy pages
+ * Dont mess with busy pages, keep in the front of the
+ * queue, most likely are being paged out.
*/
if (m->busy || (m->flags & PG_BUSY)) {
m = next;
@@ -600,8 +584,6 @@ rescan1:
m->flags &= ~PG_REFERENCED;
pmap_clear_reference(VM_PAGE_TO_PHYS(m));
vm_page_activate(m);
- if (m->act_count < ACT_MAX)
- m->act_count += ACT_ADVANCE;
m = next;
continue;
}
@@ -681,14 +663,11 @@ rescan1:
page_shortage = 1;
}
}
- maxscan = MAXSCAN;
- pcount = cnt.v_active_count;
- m = vm_page_queue_active.tqh_first;
- while ((m != NULL) && (maxscan > 0) &&
- (pcount-- > 0) && (page_shortage > 0)) {
- cnt.v_pdpages++;
- next = m->pageq.tqe_next;
+ pcount = cnt.v_active_count;
+ m = TAILQ_FIRST(&vm_page_queue_active);
+ while ((m != NULL) && (pcount-- > 0) && (page_shortage > 0)) {
+ next = TAILQ_NEXT(m, pageq);
/*
* Don't deactivate pages that are busy.
@@ -701,54 +680,47 @@ rescan1:
m = next;
continue;
}
- if (m->object->ref_count &&
- ((m->flags & PG_REFERENCED) ||
- pmap_is_referenced(VM_PAGE_TO_PHYS(m))) ) {
+
+ /*
+ * The count for pagedaemon pages is done after checking the
+ * page for eligbility...
+ */
+ cnt.v_pdpages++;
+ if ((m->flags & PG_REFERENCED) == 0) {
+ if (pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
+ pmap_clear_reference(VM_PAGE_TO_PHYS(m));
+ m->flags |= PG_REFERENCED;
+ }
+ } else {
pmap_clear_reference(VM_PAGE_TO_PHYS(m));
+ }
+ if ( (m->object->ref_count != 0) &&
+ (m->flags & PG_REFERENCED) ) {
m->flags &= ~PG_REFERENCED;
- if (m->act_count < ACT_MAX) {
- m->act_count += ACT_ADVANCE;
- }
TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
} else {
m->flags &= ~PG_REFERENCED;
- pmap_clear_reference(VM_PAGE_TO_PHYS(m));
- m->act_count -= min(m->act_count, ACT_DECLINE);
-
- /*
- * if the page act_count is zero -- then we deactivate
- */
- if (!m->act_count && (page_shortage > 0)) {
- if (m->object->ref_count == 0) {
- --page_shortage;
- vm_page_test_dirty(m);
- if (m->dirty == 0) {
- m->act_count = 0;
- vm_page_cache(m);
- } else {
- vm_page_deactivate(m);
- }
+ if (page_shortage > 0) {
+ --page_shortage;
+ vm_page_test_dirty(m);
+ if (m->dirty == 0) {
+ vm_page_cache(m);
} else {
vm_page_protect(m, VM_PROT_NONE);
vm_page_deactivate(m);
- --page_shortage;
}
- } else if (m->act_count) {
- TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
- TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
}
}
- maxscan--;
m = next;
}
-
+
/*
* We try to maintain some *really* free pages, this allows interrupt
* code to be guaranteed space.
*/
while (cnt.v_free_count < cnt.v_free_reserved) {
- m = vm_page_queue_cache.tqh_first;
+ m = TAILQ_FIRST(&vm_page_queue_cache);
if (!m)
break;
vm_page_free(m);
@@ -770,23 +742,13 @@ rescan1:
}
}
#ifndef NO_SWAPPING
- /*
- * now swap processes out if we are in low memory conditions
- */
- if (!swap_pager_full && vm_swap_size &&
- vm_pageout_req_swapout == 0) {
- vm_pageout_req_swapout = 1;
+ if (cnt.v_free_count + cnt.v_cache_count < cnt.v_free_target) {
vm_req_vmdaemon();
+ vm_pageout_req_swapout = 1;
}
#endif
}
-#ifndef NO_SWAPPING
- if ((cnt.v_inactive_count + cnt.v_free_count + cnt.v_cache_count) <
- (cnt.v_inactive_target + cnt.v_free_min)) {
- vm_req_vmdaemon();
- }
-#endif
/*
* make sure that we have swap space -- if we are low on memory and
@@ -883,22 +845,23 @@ vm_pageout()
* The pageout daemon is never done, so loop forever.
*/
while (TRUE) {
- int s = splhigh();
-
+ int s = splvm();
if (!vm_pages_needed ||
((cnt.v_free_count >= cnt.v_free_reserved) &&
(cnt.v_free_count + cnt.v_cache_count >= cnt.v_free_min))) {
vm_pages_needed = 0;
tsleep(&vm_pages_needed, PVM, "psleep", 0);
+ } else if (!vm_pages_needed) {
+ tsleep(&vm_pages_needed, PVM, "psleep", hz/3);
}
+ if (vm_pages_needed)
+ cnt.v_pdwakeups++;
vm_pages_needed = 0;
splx(s);
- cnt.v_pdwakeups++;
vm_pager_sync();
vm_pageout_scan();
vm_pager_sync();
wakeup(&cnt.v_free_count);
- wakeup(kmem_map);
}
}
@@ -908,7 +871,7 @@ vm_req_vmdaemon()
{
static int lastrun = 0;
- if ((ticks > (lastrun + hz / 10)) || (ticks < lastrun)) {
+ if ((ticks > (lastrun + hz)) || (ticks < lastrun)) {
wakeup(&vm_daemon_needed);
lastrun = ticks;
}
@@ -978,7 +941,7 @@ vm_daemon()
* we remove cached objects that have no RSS...
*/
restart:
- object = vm_object_cached_list.tqh_first;
+ object = TAILQ_FIRST(&vm_object_cached_list);
while (object) {
/*
* if there are no resident pages -- get rid of the object
@@ -988,7 +951,7 @@ restart:
pager_cache(object, FALSE);
goto restart;
}
- object = object->cached_list.tqe_next;
+ object = TAILQ_NEXT(object, cached_list);
}
}
}
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index 63ebdd9..c7c9964 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pager.c,v 1.21 1995/12/14 09:55:11 phk Exp $
+ * $Id: vm_pager.c,v 1.22 1996/05/03 21:01:53 phk Exp $
*/
/*
@@ -249,7 +249,7 @@ vm_pager_object_lookup(pg_list, handle)
{
register vm_object_t object;
- for (object = pg_list->tqh_first; object != NULL; object = object->pager_object_list.tqe_next)
+ for (object = TAILQ_FIRST(pg_list); object != NULL; object = TAILQ_NEXT(object,pager_object_list))
if (object->handle == handle)
return (object);
return (NULL);
@@ -288,7 +288,7 @@ getpbuf()
s = splbio();
/* get a bp from the swap buffer header pool */
- while ((bp = bswlist.tqh_first) == NULL) {
+ while ((bp = TAILQ_FIRST(&bswlist)) == NULL) {
bswneeded = 1;
tsleep(&bswneeded, PVM, "wswbuf", 0);
}
@@ -313,7 +313,7 @@ trypbuf()
struct buf *bp;
s = splbio();
- if ((bp = bswlist.tqh_first) == NULL) {
+ if ((bp = TAILQ_FIRST(&bswlist)) == NULL) {
splx(s);
return NULL;
}
OpenPOWER on IntegriCloud