summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2002-01-02 22:23:25 +0000
committermiod <miod@openbsd.org>2002-01-02 22:23:25 +0000
commit2c932f6f6824a716632a22bf391dae01a1befc69 (patch)
treeee5473d11813975cf7d706c91fb104bd8af32017
parentAdd more vocabulary (commands) to ddb, from NetBSD. (diff)
downloadwireguard-openbsd-2c932f6f6824a716632a22bf391dae01a1befc69.tar.xz
wireguard-openbsd-2c932f6f6824a716632a22bf391dae01a1befc69.zip
Back out a few more uvm changes, especially wrt swap usage.
This unbreaks m68k m88k sparc and perhaps others, which eventually froze when hitting swap. Tested by various people on various platforms. ok art@
-rw-r--r--sys/uvm/uvm_amap.c14
-rw-r--r--sys/uvm/uvm_anon.c33
-rw-r--r--sys/uvm/uvm_fault.c62
-rw-r--r--sys/uvm/uvm_loan.c15
-rw-r--r--sys/uvm/uvm_map.c25
-rw-r--r--sys/uvm/uvm_page.c27
-rw-r--r--sys/uvm/uvm_page_i.h7
-rw-r--r--sys/uvm/uvm_pager.c50
-rw-r--r--sys/uvm/uvm_pdaemon.c88
-rw-r--r--sys/uvm/uvm_swap.c35
10 files changed, 150 insertions, 206 deletions
diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c
index 29263bf7d60..11043fd0ff7 100644
--- a/sys/uvm/uvm_amap.c
+++ b/sys/uvm/uvm_amap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_amap.c,v 1.18 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_amap.c,v 1.30 2001/02/18 21:19:09 chs Exp $ */
+/* $OpenBSD: uvm_amap.c,v 1.19 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
/*
*
@@ -255,7 +255,6 @@ amap_free(amap)
UVMHIST_FUNC("amap_free"); UVMHIST_CALLED(maphist);
KASSERT(amap->am_ref == 0 && amap->am_nused == 0);
- LOCK_ASSERT(simple_lock_held(&amap->am_l));
free(amap->am_slots, M_UVMAMAP);
free(amap->am_bckptr, M_UVMAMAP);
@@ -458,8 +457,6 @@ amap_share_protect(entry, prot)
struct vm_amap *amap = entry->aref.ar_amap;
int slots, lcv, slot, stop;
- LOCK_ASSERT(simple_lock_held(&amap->am_l));
-
AMAP_B2SLOT(slots, (entry->end - entry->start));
stop = entry->aref.ar_pageoff + slots;
@@ -503,8 +500,6 @@ amap_wipeout(amap)
UVMHIST_FUNC("amap_wipeout"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist,"(amap=0x%x)", amap, 0,0,0);
- LOCK_ASSERT(simple_lock_held(&amap->am_l));
-
for (lcv = 0 ; lcv < amap->am_nused ; lcv++) {
int refs;
@@ -792,7 +787,6 @@ ReStart:
*/
nanon = uvm_analloc();
if (nanon) {
- /* nanon is locked! */
npg = uvm_pagealloc(NULL, 0, nanon, 0);
} else
npg = NULL; /* XXX: quiet gcc warning */
@@ -804,8 +798,7 @@ ReStart:
* we can't ...
*/
if (nanon) {
- nanon->an_ref--;
- simple_unlock(&nanon->an_lock);
+ simple_lock(&nanon->an_lock);
uvm_anfree(nanon);
}
simple_unlock(&anon->an_lock);
@@ -832,7 +825,6 @@ ReStart:
uvm_lock_pageq();
uvm_pageactivate(npg);
uvm_unlock_pageq();
- simple_unlock(&nanon->an_lock);
}
simple_unlock(&anon->an_lock);
diff --git a/sys/uvm/uvm_anon.c b/sys/uvm/uvm_anon.c
index 9cf22f1f21f..658e7d7e9c1 100644
--- a/sys/uvm/uvm_anon.c
+++ b/sys/uvm/uvm_anon.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_anon.c,v 1.19 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_anon.c,v 1.15 2001/02/18 21:19:08 chs Exp $ */
+/* $OpenBSD: uvm_anon.c,v 1.20 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $ */
/*
*
@@ -103,13 +103,15 @@ uvm_anon_add(count)
if (needed <= 0) {
return 0;
}
+
anon = (void *)uvm_km_alloc(kernel_map, sizeof(*anon) * needed);
+
+ /* XXX Should wait for VM to free up. */
if (anon == NULL) {
- simple_lock(&uvm.afreelock);
- uvmexp.nanonneeded -= count;
- simple_unlock(&uvm.afreelock);
- return ENOMEM;
+ printf("uvm_anon_add: can not allocate %d anons\n", needed);
+ panic("uvm_anon_add");
}
+
MALLOC(anonblock, void *, sizeof(*anonblock), M_UVMAMAP, M_WAITOK);
anonblock->count = needed;
@@ -149,8 +151,6 @@ uvm_anon_remove(count)
/*
* allocate an anon
- *
- * => new anon is returned locked!
*/
struct vm_anon *
uvm_analloc()
@@ -165,8 +165,6 @@ uvm_analloc()
a->an_ref = 1;
a->an_swslot = 0;
a->u.an_page = NULL; /* so we can free quickly */
- LOCK_ASSERT(simple_lock_held(&a->an_lock) == 0);
- simple_lock(&a->an_lock);
}
simple_unlock(&uvm.afreelock);
return(a);
@@ -188,9 +186,6 @@ uvm_anfree(anon)
UVMHIST_FUNC("uvm_anfree"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist,"(anon=0x%x)", anon, 0,0,0);
- KASSERT(anon->an_ref == 0);
- LOCK_ASSERT(simple_lock_held(&anon->an_lock) == 0);
-
/*
* get page
*/
@@ -321,8 +316,6 @@ uvm_anon_lockloanpg(anon)
struct vm_page *pg;
boolean_t locked = FALSE;
- LOCK_ASSERT(simple_lock_held(&anon->an_lock));
-
/*
* loop while we have a resident page that has a non-zero loan count.
* if we successfully get our lock, we will "break" the loop.
@@ -477,10 +470,7 @@ anon_pagein(anon)
int rv;
/* locked: anon */
- LOCK_ASSERT(simple_lock_held(&anon->an_lock));
-
rv = uvmfault_anonget(NULL, NULL, anon);
-
/*
* if rv == VM_PAGER_OK, anon is still locked, else anon
* is unlocked
@@ -500,6 +490,13 @@ anon_pagein(anon)
*/
return FALSE;
+
+ default:
+#ifdef DIAGNOSTIC
+ panic("anon_pagein: uvmfault_anonget -> %d", rv);
+#else
+ return FALSE;
+#endif
}
/*
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index 6736aa6a8d5..7f7b9c97e89 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_fault.c,v 1.29 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_fault.c,v 1.56 2001/02/18 21:19:08 chs Exp $ */
+/* $OpenBSD: uvm_fault.c,v 1.30 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/*
*
@@ -303,8 +303,6 @@ uvmfault_anonget(ufi, amap, anon)
int result;
UVMHIST_FUNC("uvmfault_anonget"); UVMHIST_CALLED(maphist);
- LOCK_ASSERT(simple_lock_held(&anon->an_lock));
-
result = 0; /* XXX shut up gcc */
uvmexp.fltanget++;
/* bump rusage counters */
@@ -893,7 +891,7 @@ ReFault:
/* locked: maps(read), amap (if there), uobj */
result = uobj->pgops->pgo_fault(&ufi, startva, pages, npages,
centeridx, fault_type, access_type,
- PGO_LOCKED|PGO_SYNCIO);
+ PGO_LOCKED);
/* locked: nothing, pgo_fault has unlocked everything */
@@ -990,8 +988,7 @@ ReFault:
(void) pmap_enter(ufi.orig_map->pmap, currva,
VM_PAGE_TO_PHYS(pages[lcv]),
- pages[lcv]->flags & PG_RDONLY ?
- VM_PROT_READ : enter_prot & MASK(ufi.entry),
+ enter_prot & MASK(ufi.entry),
PMAP_CANFAIL |
(wired ? PMAP_WIRED : 0));
@@ -1070,9 +1067,13 @@ ReFault:
case VM_PAGER_REFAULT:
goto ReFault;
- case VM_PAGER_AGAIN:
- tsleep(&lbolt, PVM, "fltagain1", 0);
- goto ReFault;
+ case VM_PAGER_ERROR:
+ /*
+ * An error occured while trying to bring in the
+ * page -- this is the only error we return right
+ * now.
+ */
+ return (KERN_PROTECTION_FAILURE); /* XXX */
default:
#ifdef DIAGNOSTIC
@@ -1186,17 +1187,13 @@ ReFault:
oanon = anon; /* oanon = old, locked anon */
anon = uvm_analloc();
if (anon) {
- /* new anon is locked! */
pg = uvm_pagealloc(NULL, 0, anon, 0);
}
/* check for out of RAM */
if (anon == NULL || pg == NULL) {
- if (anon) {
- anon->an_ref--;
- simple_unlock(&anon->an_lock);
+ if (anon)
uvm_anfree(anon);
- }
uvmfault_unlockall(&ufi, amap, uobj, oanon);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (anon == NULL || uvmexp.swpgonly == uvmexp.swpages) {
@@ -1223,9 +1220,9 @@ ReFault:
oanon->an_ref--;
/*
- * note: oanon is still locked, as is the new anon. we
- * need to check for this later when we unlock oanon; if
- * oanon != anon, we'll have to unlock anon, too.
+ * note: oanon still locked. anon is _not_ locked, but we
+ * have the sole references to in from amap which _is_ locked.
+ * thus, no one can get at it until we are done with it.
*/
} else {
@@ -1238,7 +1235,7 @@ ReFault:
}
- /* locked: maps(read), amap, oanon, anon (if different from oanon) */
+ /* locked: maps(read), amap, oanon */
/*
* now map the page in ...
@@ -1259,8 +1256,6 @@ ReFault:
* We do, however, have to go through the ReFault path,
* as the map may change while we're asleep.
*/
- if (anon != oanon)
- simple_unlock(&anon->an_lock);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (uvmexp.swpgonly == uvmexp.swpages) {
@@ -1303,8 +1298,6 @@ ReFault:
* done case 1! finish up by unlocking everything and returning success
*/
- if (anon != oanon)
- simple_unlock(&anon->an_lock);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
return (KERN_SUCCESS);
@@ -1484,9 +1477,6 @@ Case2:
* set "pg" to the page we want to map in (uobjpage, usually)
*/
- /* no anon in this case. */
- anon = NULL;
-
uvmexp.flt_obj++;
if (UVM_ET_ISCOPYONWRITE(ufi.entry))
enter_prot &= ~VM_PROT_WRITE;
@@ -1589,8 +1579,6 @@ Case2:
anon = uvm_analloc();
if (anon) {
/*
- * The new anon is locked.
- *
* In `Fill in data...' below, if
* uobjpage == PGO_DONTCARE, we want
* a zero'd, dirty page, so have
@@ -1605,12 +1593,6 @@ Case2:
*/
if (anon == NULL || pg == NULL) {
- if (anon != NULL) {
- anon->an_ref--;
- simple_unlock(&anon->an_lock);
- uvm_anfree(anon);
- }
-
/*
* arg! must unbusy our page and fail or sleep.
*/
@@ -1638,6 +1620,7 @@ Case2:
UVMHIST_LOG(maphist, " out of RAM, waiting for more",
0,0,0,0);
+ uvm_anfree(anon);
uvmexp.fltnoram++;
uvm_wait("flt_noram5");
goto ReFault;
@@ -1697,8 +1680,7 @@ Case2:
/*
* locked:
- * maps(read), amap(if !null), uobj(if !null), uobjpage(if uobj),
- * anon(if !null), pg(if anon)
+ * maps(read), amap(if !null), uobj(if !null), uobjpage(if uobj)
*
* note: pg is either the uobjpage or the new page in the new anon
*/
@@ -1711,10 +1693,8 @@ Case2:
UVMHIST_LOG(maphist,
" MAPPING: case2: pm=0x%x, va=0x%x, pg=0x%x, promote=%d",
ufi.orig_map->pmap, ufi.orig_rvaddr, pg, promote);
- KASSERT(access_type == VM_PROT_READ || (pg->flags & PG_RDONLY) == 0);
if (pmap_enter(ufi.orig_map->pmap, ufi.orig_rvaddr, VM_PAGE_TO_PHYS(pg),
- pg->flags & PG_RDONLY ? VM_PROT_READ : enter_prot,
- access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0))
+ enter_prot, access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0))
!= KERN_SUCCESS) {
/*
@@ -1735,7 +1715,7 @@ Case2:
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
- uvmfault_unlockall(&ufi, amap, uobj, anon);
+ uvmfault_unlockall(&ufi, amap, uobj, NULL);
KASSERT(uvmexp.swpgonly <= uvmexp.swpages);
if (uvmexp.swpgonly == uvmexp.swpages) {
UVMHIST_LOG(maphist,
@@ -1780,7 +1760,7 @@ Case2:
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
- uvmfault_unlockall(&ufi, amap, uobj, anon);
+ uvmfault_unlockall(&ufi, amap, uobj, NULL);
UVMHIST_LOG(maphist, "<- done (SUCCESS!)",0,0,0,0);
return (KERN_SUCCESS);
diff --git a/sys/uvm/uvm_loan.c b/sys/uvm/uvm_loan.c
index e3c99ea8bb9..6ffea0dbd4f 100644
--- a/sys/uvm/uvm_loan.c
+++ b/sys/uvm/uvm_loan.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_loan.c,v 1.17 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_loan.c,v 1.23 2001/01/23 02:27:39 thorpej Exp $ */
+/* $OpenBSD: uvm_loan.c,v 1.18 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_loan.c,v 1.22 2000/06/27 17:29:25 mrg Exp $ */
/*
*
@@ -579,7 +579,6 @@ uvm_loanuobj(ufi, output, flags, va)
uvmfault_unlockall(ufi, amap, uobj, NULL);
return(-1);
}
- /* anon is locked! */
anon->u.an_page = pg;
pg->uanon = anon;
uvm_lock_pageq();
@@ -594,7 +593,6 @@ uvm_loanuobj(ufi, output, flags, va)
wakeup(pg);
pg->flags &= ~(PG_WANTED|PG_BUSY);
UVM_PAGE_OWN(pg, NULL);
- simple_unlock(&anon->an_lock);
return(1);
}
@@ -653,19 +651,12 @@ uvm_loanzero(ufi, output, flags)
/* unlock everything */
uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap,
- ufi->entry->object.uvm_obj, anon);
+ ufi->entry->object.uvm_obj, NULL);
/* out of swap causes us to fail */
if (anon == NULL)
return(-1);
- /*
- * drop our reference; we're the only one,
- * so it's okay that the anon isn't locked
- * here.
- */
- anon->an_ref--;
-
uvm_anfree(anon);
uvm_wait("loanzero2"); /* wait for pagedaemon */
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index 058d8e53d80..710211c79ae 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_map.c,v 1.35 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_map.c,v 1.93 2001/02/11 01:34:23 eeh Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.36 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -2439,6 +2439,8 @@ uvm_map_pageable_all(map, flags, limit)
* => we may sleep while cleaning if SYNCIO [with map read-locked]
*/
+int amap_clean_works = 1; /* XXX for now, just in case... */
+
int
uvm_map_clean(map, start, end, flags)
vm_map_t map;
@@ -2476,10 +2478,8 @@ uvm_map_clean(map, start, end, flags)
vm_map_unlock_read(map);
return (KERN_INVALID_ARGUMENT);
}
- if (end <= current->end) {
- break;
- }
- if (current->end != current->next->start) {
+ if (end > current->end && (current->next == &map->header ||
+ current->end != current->next->start)) {
vm_map_unlock_read(map);
return (KERN_INVALID_ADDRESS);
}
@@ -2487,7 +2487,7 @@ uvm_map_clean(map, start, end, flags)
error = KERN_SUCCESS;
- for (current = entry; start < end; current = current->next) {
+ for (current = entry; current->start < end; current = current->next) {
amap = current->aref.ar_amap; /* top layer */
uobj = current->object.uvm_obj; /* bottom layer */
KASSERT(start >= current->start);
@@ -2503,6 +2503,10 @@ uvm_map_clean(map, start, end, flags)
if (amap == NULL || (flags & (PGO_DEACTIVATE|PGO_FREE)) == 0)
goto flush_object;
+ /* XXX for now, just in case... */
+ if (amap_clean_works == 0)
+ goto flush_object;
+
amap_lock(amap);
offset = start - current->start;
size = MIN(end, current->end) - start;
@@ -2555,8 +2559,15 @@ uvm_map_clean(map, start, end, flags)
}
KASSERT(pg->uanon == anon);
+#ifdef UBC
/* ...and deactivate the page. */
pmap_clear_reference(pg);
+#else
+ /* zap all mappings for the page. */
+ pmap_page_protect(pg, VM_PROT_NONE);
+
+ /* ...and deactivate the page. */
+#endif
uvm_pagedeactivate(pg);
uvm_unlock_pageq();
diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c
index edfb5b1ca31..528cb911d22 100644
--- a/sys/uvm/uvm_page.c
+++ b/sys/uvm/uvm_page.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_page.c,v 1.39 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_page.c,v 1.51 2001/03/09 01:02:12 chs Exp $ */
+/* $OpenBSD: uvm_page.c,v 1.40 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -187,11 +187,11 @@ uvm_pageremove(pg)
simple_unlock(&uvm.hashlock);
splx(s);
- if (UVM_OBJ_IS_VTEXT(pg->uobject)) {
- uvmexp.vtextpages--;
- } else if (UVM_OBJ_IS_VNODE(pg->uobject)) {
- uvmexp.vnodepages--;
+#ifdef UBC
+ if (pg->uobject->pgops == &uvm_vnodeops) {
+ uvm_pgcnt_vnode--;
}
+#endif
/* object should be locked */
TAILQ_REMOVE(&pg->uobject->memq, pg, listq);
@@ -895,10 +895,6 @@ uvm_pagealloc_strat(obj, off, anon, flags, strat, free_list)
KASSERT(obj == NULL || anon == NULL);
KASSERT(off == trunc_page(off));
-
- LOCK_ASSERT(obj == NULL || simple_lock_held(&obj->vmobjlock));
- LOCK_ASSERT(anon == NULL || simple_lock_held(&anon->an_lock));
-
s = uvm_lock_fpageq();
/*
@@ -1024,7 +1020,9 @@ uvm_pagealloc_strat(obj, off, anon, flags, strat, free_list)
if (anon) {
anon->u.an_page = pg;
pg->pqflags = PQ_ANON;
- uvmexp.anonpages++;
+#ifdef UBC
+ uvm_pgcnt_anon++;
+#endif
} else {
if (obj)
uvm_pageinsert(pg);
@@ -1181,10 +1179,11 @@ uvm_pagefree(pg)
pg->wire_count = 0;
uvmexp.wired--;
}
-
+#ifdef UBC
if (pg->uanon) {
- uvmexp.anonpages--;
+ uvm_pgcnt_anon--;
}
+#endif
/*
* and put on free queue
@@ -1248,8 +1247,6 @@ uvm_page_unbusy(pgs, npgs)
}
} else {
UVMHIST_LOG(ubchist, "unbusying pg %p", pg,0,0,0);
- KASSERT(pg->wire_count ||
- (pg->pqflags & (PQ_ACTIVE|PQ_INACTIVE)));
pg->flags &= ~(PG_WANTED|PG_BUSY);
UVM_PAGE_OWN(pg, NULL);
}
diff --git a/sys/uvm/uvm_page_i.h b/sys/uvm/uvm_page_i.h
index 024c692b5b9..8c6d71288e9 100644
--- a/sys/uvm/uvm_page_i.h
+++ b/sys/uvm/uvm_page_i.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_page_i.h,v 1.13 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_page_i.h,v 1.16 2001/01/28 23:30:45 thorpej Exp $ */
+/* $OpenBSD: uvm_page_i.h,v 1.14 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_page_i.h,v 1.14 2000/11/27 07:47:42 chs Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -194,12 +194,11 @@ uvm_pageunwire(pg)
}
/*
- * uvm_pagedeactivate: deactivate page
+ * uvm_pagedeactivate: deactivate page -- no pmaps have access to page
*
* => caller must lock page queues
* => caller must check to make sure page is not wired
* => object that page belongs to must be locked (so we can adjust pg->flags)
- * => caller must clear the reference on the page before calling
*/
PAGE_INLINE void
diff --git a/sys/uvm/uvm_pager.c b/sys/uvm/uvm_pager.c
index 5c93fe9f9db..46972ccf57d 100644
--- a/sys/uvm/uvm_pager.c
+++ b/sys/uvm/uvm_pager.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_pager.c,v 1.29 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_pager.c,v 1.41 2001/02/18 19:26:50 chs Exp $ */
+/* $OpenBSD: uvm_pager.c,v 1.30 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_pager.c,v 1.36 2000/11/27 18:26:41 chs Exp $ */
/*
*
@@ -187,8 +187,7 @@ enter:
KASSERT(pp);
KASSERT(pp->flags & PG_BUSY);
pmap_enter(vm_map_pmap(pager_map), cva, VM_PAGE_TO_PHYS(pp),
- prot, PMAP_WIRED | ((pp->flags & PG_FAKE) ? prot :
- VM_PROT_READ));
+ prot, PMAP_WIRED | prot);
}
UVMHIST_LOG(maphist, "<- done (KVA=0x%x)", kva,0,0,0);
@@ -315,6 +314,11 @@ uvm_mk_pcluster(uobj, pps, npages, center, flags, mlo, mhi)
/*
* attempt to cluster around the left [backward], and then
* the right side [forward].
+ *
+ * note that for inactive pages (pages that have been deactivated)
+ * there are no valid mappings and PG_CLEAN should be up to date.
+ * [i.e. there is no need to query the pmap with pmap_is_modified
+ * since there are no mappings].
*/
for (forward = 0 ; forward <= 1 ; forward++) {
@@ -328,28 +332,23 @@ uvm_mk_pcluster(uobj, pps, npages, center, flags, mlo, mhi)
if (pclust == NULL) {
break; /* no page */
}
+ /* handle active pages */
+ /* NOTE: inactive pages don't have pmap mappings */
+ if ((pclust->pqflags & PQ_INACTIVE) == 0) {
+ if ((flags & PGO_DOACTCLUST) == 0) {
+ /* dont want mapped pages at all */
+ break;
+ }
- if ((flags & PGO_DOACTCLUST) == 0) {
- /* dont want mapped pages at all */
- break;
- }
-
- /*
- * get an up-to-date view of the "clean" bit.
- * note this isn't 100% accurate, but it doesn't
- * have to be. if it's not quite right, the
- * worst that happens is we don't cluster as
- * aggressively. we'll sync-it-for-sure before
- * we free the page, and clean it if necessary.
- */
- if ((pclust->flags & PG_CLEANCHK) == 0) {
- if ((pclust->flags & (PG_CLEAN|PG_BUSY))
- == PG_CLEAN &&
- pmap_is_modified(pclust))
- pclust->flags &= ~PG_CLEAN;
-
- /* now checked */
- pclust->flags |= PG_CLEANCHK;
+ /* make sure "clean" bit is sync'd */
+ if ((pclust->flags & PG_CLEANCHK) == 0) {
+ if ((pclust->flags & (PG_CLEAN|PG_BUSY))
+ == PG_CLEAN &&
+ pmap_is_modified(pclust))
+ pclust->flags &= ~PG_CLEAN;
+ /* now checked */
+ pclust->flags |= PG_CLEANCHK;
+ }
}
/* is page available for cleaning and does it need it */
@@ -862,7 +861,6 @@ uvm_aio_aiodone(bp)
pgs[i]->flags |= PG_CLEAN;
pgs[i]->flags &= ~PG_FAKE;
}
- uvm_pageactivate(pg);
if (swap) {
if (pg->pqflags & PQ_ANON) {
simple_unlock(&pg->uanon->an_lock);
diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c
index 42fa8b0809d..6d8d8719d6b 100644
--- a/sys/uvm/uvm_pdaemon.c
+++ b/sys/uvm/uvm_pdaemon.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_pdaemon.c,v 1.21 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_pdaemon.c,v 1.30 2001/03/09 01:02:12 chs Exp $ */
+/* $OpenBSD: uvm_pdaemon.c,v 1.22 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -164,12 +164,12 @@ uvmpd_tune()
{
UVMHIST_FUNC("uvmpd_tune"); UVMHIST_CALLED(pdhist);
- uvmexp.freemin = uvmexp.npages / 20;
+ uvmexp.freemin = uvmexp.npages / 30;
- /* between 16k and 256k */
+ /* between 16k and 512k */
/* XXX: what are these values good for? */
uvmexp.freemin = max(uvmexp.freemin, (16*1024) >> PAGE_SHIFT);
- uvmexp.freemin = min(uvmexp.freemin, (256*1024) >> PAGE_SHIFT);
+ uvmexp.freemin = min(uvmexp.freemin, (512*1024) >> PAGE_SHIFT);
/* Make sure there's always a user page free. */
if (uvmexp.freemin < uvmexp.reserve_kernel + 1)
@@ -248,8 +248,16 @@ uvm_pageout(void *arg)
* scan if needed
*/
+#ifdef UBC
if (uvmexp.free + uvmexp.paging < uvmexp.freetarg ||
+ uvmexp.inactive < uvmexp.inactarg ||
+ uvm_pgcnt_vnode >
+ (uvmexp.active + uvmexp.inactive + uvmexp.wired +
+ uvmexp.free) * 13 / 16) {
+#else
+ if (uvmexp.free < uvmexp.freetarg ||
uvmexp.inactive < uvmexp.inactarg) {
+#endif
uvmpd_scan();
}
@@ -369,7 +377,7 @@ uvmpd_scan_inactive(pglst)
struct vm_anon *anon;
boolean_t swap_backed;
vaddr_t start;
- int dirtyreacts, t;
+ int dirtyreacts;
UVMHIST_FUNC("uvmpd_scan_inactive"); UVMHIST_CALLED(pdhist);
/*
@@ -438,7 +446,9 @@ uvmpd_scan_inactive(pglst)
/*
* move referenced pages back to active queue and
- * skip to next page.
+ * skip to next page (unlikely to happen since
+ * inactive pages shouldn't have any valid mappings
+ * and we cleared reference before deactivating).
*/
if (pmap_is_referenced(p)) {
@@ -448,35 +458,6 @@ uvmpd_scan_inactive(pglst)
}
/*
- * enforce the minimum thresholds on different
- * types of memory usage. if reusing the current
- * page would reduce that type of usage below its
- * minimum, reactivate the page instead and move
- * on to the next page.
- */
-
- t = uvmexp.active + uvmexp.inactive + uvmexp.free;
- if (p->uanon &&
- uvmexp.anonpages <= (t * uvmexp.anonmin) >> 8) {
- uvm_pageactivate(p);
- uvmexp.pdreanon++;
- continue;
- }
- if (p->uobject && UVM_OBJ_IS_VTEXT(p->uobject) &&
- uvmexp.vtextpages <= (t * uvmexp.vtextmin) >> 8) {
- uvm_pageactivate(p);
- uvmexp.pdrevtext++;
- continue;
- }
- if (p->uobject && UVM_OBJ_IS_VNODE(p->uobject) &&
- !UVM_OBJ_IS_VTEXT(p->uobject) &&
- uvmexp.vnodepages <= (t * uvmexp.vnodemin) >> 8) {
- uvm_pageactivate(p);
- uvmexp.pdrevnode++;
- continue;
- }
-
- /*
* first we attempt to lock the object that this page
* belongs to. if our attempt fails we skip on to
* the next page (no harm done). it is important to
@@ -537,17 +518,10 @@ uvmpd_scan_inactive(pglst)
/*
* we now have the object and the page queues locked.
- * the page is not busy. remove all the permissions
- * from the page so we can sync the modified info
- * without any race conditions. if the page is clean
- * we can free it now and continue.
+ * the page is not busy. if the page is clean we
+ * can free it now and continue.
*/
- pmap_page_protect(p, VM_PROT_NONE);
- if ((p->flags & PG_CLEAN) != 0 && pmap_is_modified(p)) {
- p->flags &= ~PG_CLEAN;
- }
-
if (p->flags & PG_CLEAN) {
if (p->pqflags & PQ_SWAPBACKED) {
/* this page now lives only in swap */
@@ -556,6 +530,8 @@ uvmpd_scan_inactive(pglst)
simple_unlock(&uvm.swap_data_lock);
}
+ /* zap all mappings with pmap_page_protect... */
+ pmap_page_protect(p, VM_PROT_NONE);
uvm_pagefree(p);
uvmexp.pdfreed++;
@@ -638,12 +614,15 @@ uvmpd_scan_inactive(pglst)
* the page we are looking at is dirty. we must
* clean it before it can be freed. to do this we
* first mark the page busy so that no one else will
- * touch the page.
+ * touch the page. we write protect all the mappings
+ * of the page so that no one touches it while it is
+ * in I/O.
*/
swap_backed = ((p->pqflags & PQ_SWAPBACKED) != 0);
p->flags |= PG_BUSY; /* now we own it */
UVM_PAGE_OWN(p, "scan_inactive");
+ pmap_page_protect(p, VM_PROT_READ);
uvmexp.pgswapout++;
/*
@@ -816,6 +795,7 @@ uvmpd_scan_inactive(pglst)
continue;
}
+#ifdef UBC
if (result == VM_PAGER_ERROR &&
curproc == uvm.pagedaemon_proc) {
uvm_lock_pageq();
@@ -823,6 +803,7 @@ uvmpd_scan_inactive(pglst)
uvm_pageactivate(p);
continue;
}
+#endif
/*
* clean up "p" if we have one
@@ -859,6 +840,12 @@ uvmpd_scan_inactive(pglst)
simple_lock(&uobj->vmobjlock);
}
+#ifdef DIAGNOSTIC
+ if (result == VM_PAGER_UNLOCK)
+ panic("pagedaemon: pageout returned "
+ "invalid 'unlock' code");
+#endif
+
/* handle PG_WANTED now */
if (p->flags & PG_WANTED)
/* still holding object lock */
@@ -1108,13 +1095,12 @@ uvmpd_scan()
}
/*
- * If the page has not been referenced since the
- * last scan, deactivate the page if there is a
- * shortage of inactive pages.
+ * deactivate this page if there's a shortage of
+ * inactive pages.
*/
- if (inactive_shortage > 0 &&
- pmap_clear_reference(p) == FALSE) {
+ if (inactive_shortage > 0) {
+ pmap_page_protect(p, VM_PROT_NONE);
/* no need to check wire_count as pg is "active" */
uvm_pagedeactivate(p);
uvmexp.pddeact++;
diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c
index 3ed77ab3555..40eca607eae 100644
--- a/sys/uvm/uvm_swap.c
+++ b/sys/uvm/uvm_swap.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uvm_swap.c,v 1.47 2001/12/19 08:58:07 art Exp $ */
-/* $NetBSD: uvm_swap.c,v 1.46 2001/02/18 21:19:08 chs Exp $ */
+/* $OpenBSD: uvm_swap.c,v 1.48 2002/01/02 22:23:25 miod Exp $ */
+/* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */
/*
* Copyright (c) 1995, 1996, 1997 Matthew R. Green
@@ -762,7 +762,7 @@ sys_swapctl(p, v, retval)
case SWAP_DUMPDEV:
if (vp->v_type != VBLK) {
error = ENOTBLK;
- break;
+ goto out;
}
dumpdev = vp->v_rdev;
break;
@@ -867,7 +867,9 @@ sys_swapctl(p, v, retval)
/*
* do the real work.
*/
- error = swap_off(p, sdp);
+ if ((error = swap_off(p, sdp)) != 0)
+ goto out;
+
break;
default:
@@ -1059,20 +1061,16 @@ swap_on(p, sdp)
printf("leaving %d pages of swap\n", size);
}
- /*
- * try to add anons to reflect the new swap space.
- */
-
- error = uvm_anon_add(size);
- if (error) {
- goto bad;
- }
-
/*
* add a ref to vp to reflect usage as a swap device.
*/
vref(vp);
+ /*
+ * add anons to reflect the new swap space
+ */
+ uvm_anon_add(size);
+
#ifdef UVM_SWAP_ENCRYPT
if (uvm_doswapencrypt)
uvm_swap_initcrypt(sdp, npages);
@@ -1089,17 +1087,12 @@ swap_on(p, sdp)
simple_unlock(&uvm.swap_data_lock);
return (0);
+bad:
/*
- * failure: clean up and return error.
+ * failure: close device if necessary and return error.
*/
-
-bad:
- if (sdp->swd_ex) {
- extent_destroy(sdp->swd_ex);
- }
- if (vp != rootvp) {
+ if (vp != rootvp)
(void)VOP_CLOSE(vp, FREAD|FWRITE, p->p_ucred, p);
- }
return (error);
}