Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm add uvmexp.swpgonly and use it to detect out-of-swap...
details: https://anonhg.NetBSD.org/src/rev/813835624800
branches: trunk
changeset: 467624:813835624800
user: chs <chs%NetBSD.org@localhost>
date: Fri Mar 26 17:34:15 1999 +0000
description:
add uvmexp.swpgonly and use it to detect out-of-swap conditions.
diffstat:
sys/uvm/uvm.h | 6 ++-
sys/uvm/uvm_anon.c | 44 +++++++++++++++++--------
sys/uvm/uvm_anon.h | 3 +-
sys/uvm/uvm_aobj.c | 55 +++++++++++++++++++++++---------
sys/uvm/uvm_aobj.h | 3 +-
sys/uvm/uvm_extern.h | 3 +-
sys/uvm/uvm_fault.c | 24 +++++++++++--
sys/uvm/uvm_km.c | 15 +-------
sys/uvm/uvm_stat.c | 4 +-
sys/uvm/uvm_swap.c | 88 +++++++++++++++++++++++++++++++--------------------
10 files changed, 159 insertions(+), 86 deletions(-)
diffs (truncated from 706 to 300 lines):
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm.h
--- a/sys/uvm/uvm.h Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm.h Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm.h,v 1.14 1999/03/25 18:48:49 mrg Exp $ */
+/* $NetBSD: uvm.h,v 1.15 1999/03/26 17:34:15 chs Exp $ */
/*
*
@@ -92,6 +92,7 @@
int page_nhash; /* number of buckets */
int page_hashmask; /* hash mask */
simple_lock_data_t hashlock; /* lock on page_hash array */
+
/* anon stuff */
struct vm_anon *afree; /* anon free list */
simple_lock_data_t afreelock; /* lock on anon free list */
@@ -107,6 +108,9 @@
vaddr_t pager_sva; /* start of pager VA area */
vaddr_t pager_eva; /* end of pager VA area */
+ /* swap-related items */
+ simple_lock_data_t swap_data_lock;
+
/* kernel object: to support anonymous pageable kernel memory */
struct uvm_object *kernel_object;
};
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_anon.c
--- a/sys/uvm/uvm_anon.c Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_anon.c Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_anon.c,v 1.1 1999/01/24 23:53:15 chuck Exp $ */
+/* $NetBSD: uvm_anon.c,v 1.2 1999/03/26 17:34:15 chs Exp $ */
/*
*
@@ -205,7 +205,6 @@
if ((pg->flags & PG_BUSY) != 0) {
/* tell them to dump it when done */
pg->flags |= PG_RELEASED;
- simple_unlock(&anon->an_lock);
UVMHIST_LOG(maphist,
" anon 0x%x, page 0x%x: BUSY (released!)",
anon, pg, 0, 0);
@@ -223,19 +222,9 @@
}
/*
- * are we using any backing store resources? if so, free them.
+ * free any swap resources.
*/
- if (anon->an_swslot) {
- /*
- * on backing store: no I/O in progress. sole amap reference
- * is ours and we've got it locked down. thus we can free,
- * and be done.
- */
- UVMHIST_LOG(maphist," freeing anon 0x%x, paged to swslot 0x%x",
- anon, anon->an_swslot, 0, 0);
- uvm_swap_free(anon->an_swslot, 1);
- anon->an_swslot = 0;
- }
+ uvm_anon_dropswap(anon);
/*
* now that we've stripped the data areas from the anon, free the anon
@@ -250,6 +239,33 @@
}
/*
+ * uvm_anon_dropswap: release any swap resources from this anon.
+ *
+ * => anon must be locked or have a reference count of 0.
+ */
+void
+uvm_anon_dropswap(anon)
+ struct vm_anon *anon;
+{
+ UVMHIST_FUNC("uvm_anon_dropswap"); UVMHIST_CALLED(maphist);
+ if (anon->an_swslot == 0) {
+ return;
+ }
+
+ UVMHIST_LOG(maphist,"freeing swap for anon %p, paged to swslot 0x%x",
+ anon, anon->an_swslot, 0, 0);
+ uvm_swap_free(anon->an_swslot, 1);
+ anon->an_swslot = 0;
+
+ if (anon->u.an_page == NULL) {
+ /* this page is no longer only in swap. */
+ simple_lock(&uvm.swap_data_lock);
+ uvmexp.swpgonly--;
+ simple_unlock(&uvm.swap_data_lock);
+ }
+}
+
+/*
* uvm_anon_lockloanpg: given a locked anon, lock its resident page
*
* => anon is locked by caller
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_anon.h
--- a/sys/uvm/uvm_anon.h Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_anon.h Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_anon.h,v 1.9 1999/01/24 23:53:15 chuck Exp $ */
+/* $NetBSD: uvm_anon.h,v 1.10 1999/03/26 17:34:15 chs Exp $ */
/*
*
@@ -101,5 +101,6 @@
void uvm_anon_init __P((void));
void uvm_anon_add __P((int));
struct vm_page *uvm_anon_lockloanpg __P((struct vm_anon *));
+void uvm_anon_dropswap __P((struct vm_anon *));
#endif /* _UVM_UVM_ANON_H_ */
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_aobj.c
--- a/sys/uvm/uvm_aobj.c Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_aobj.c Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_aobj.c,v 1.17 1999/03/25 18:48:49 mrg Exp $ */
+/* $NetBSD: uvm_aobj.c,v 1.18 1999/03/26 17:34:15 chs Exp $ */
/*
* Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -423,8 +423,17 @@
{
int slot = elt->slots[j];
- if (slot)
+ if (slot) {
uvm_swap_free(slot, 1);
+
+ /*
+ * this page is no longer
+ * only in swap.
+ */
+ simple_lock(&uvm.swap_data_lock);
+ uvmexp.swpgonly--;
+ simple_unlock(&uvm.swap_data_lock);
+ }
}
next = elt->list.le_next;
@@ -443,8 +452,14 @@
{
int slot = aobj->u_swslots[i];
- if (slot)
+ if (slot) {
uvm_swap_free(slot, 1);
+
+ /* this page is no longer only in swap. */
+ simple_lock(&uvm.swap_data_lock);
+ uvmexp.swpgonly--;
+ simple_unlock(&uvm.swap_data_lock);
+ }
}
FREE(aobj->u_swslots, M_UVMAOBJ);
}
@@ -661,7 +676,6 @@
busybody = FALSE;
for (pg = uobj->memq.tqh_first ; pg != NULL ; pg = pg->listq.tqe_next) {
- int swslot;
if (pg->flags & PG_BUSY) {
pg->flags |= PG_RELEASED;
@@ -669,16 +683,9 @@
continue;
}
-
/* zap the mappings, free the swap slot, free the page */
pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
-
- swslot = uao_set_swslot(&aobj->u_obj,
- pg->offset >> PAGE_SHIFT, 0);
- if (swslot) {
- uvm_swap_free(swslot, 1);
- }
-
+ uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
uvm_lock_pageq();
uvm_pagefree(pg);
uvm_unlock_pageq();
@@ -1037,7 +1044,6 @@
struct vm_page **nextpgp; /* OUT */
{
struct uvm_aobj *aobj = (struct uvm_aobj *) pg->uobject;
- int slot;
#ifdef DIAGNOSTIC
if ((pg->flags & PG_RELEASED) == 0)
@@ -1048,9 +1054,7 @@
* dispose of the page [caller handles PG_WANTED] and swap slot.
*/
pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
- slot = uao_set_swslot(&aobj->u_obj, pg->offset >> PAGE_SHIFT, 0);
- if (slot)
- uvm_swap_free(slot, 1);
+ uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
uvm_lock_pageq();
if (nextpgp)
*nextpgp = pg->pageq.tqe_next; /* next page for daemon */
@@ -1087,3 +1091,22 @@
return FALSE;
}
+
+/*
+ * uao_dropswap: release any swap resources from this aobj page.
+ *
+ * => aobj must be locked or have a reference count of 0.
+ */
+
+void
+uao_dropswap(uobj, pageidx)
+ struct uvm_object *uobj;
+ int pageidx;
+{
+ int slot;
+
+ slot = uao_set_swslot(uobj, pageidx, 0);
+ if (slot) {
+ uvm_swap_free(slot, 1);
+ }
+}
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_aobj.h
--- a/sys/uvm/uvm_aobj.h Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_aobj.h Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_aobj.h,v 1.7 1999/03/25 18:48:50 mrg Exp $ */
+/* $NetBSD: uvm_aobj.h,v 1.8 1999/03/26 17:34:15 chs Exp $ */
/*
* Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -63,6 +63,7 @@
*/
int uao_set_swslot __P((struct uvm_object *, int, int));
+void uao_dropswap __P((struct uvm_object *, int));
/*
* globals
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_extern.h Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_extern.h,v 1.22 1999/03/25 18:48:50 mrg Exp $ */
+/* $NetBSD: uvm_extern.h,v 1.23 1999/03/26 17:34:15 chs Exp $ */
/*
*
@@ -177,6 +177,7 @@
int nswapdev; /* number of configured swap devices in system */
int swpages; /* number of PAGE_SIZE'ed swap pages */
int swpginuse; /* number of swap pages in use */
+ int swpgonly; /* number of swap pages in use, not also in RAM */
int nswget; /* number of times fault calls uvm_swap_get() */
int nanon; /* number total of anon's in system */
int nfreeanon; /* number of free anon's */
diff -r 1d8551638163 -r 813835624800 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c Fri Mar 26 17:33:30 1999 +0000
+++ b/sys/uvm/uvm_fault.c Fri Mar 26 17:34:15 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.21 1999/03/25 18:48:50 mrg Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.22 1999/03/26 17:34:16 chs Exp $ */
/*
*
@@ -1146,13 +1146,18 @@
if (anon)
uvm_anfree(anon);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
- if (anon == NULL) {
+#ifdef DIAGNOSTIC
+ if (uvmexp.swpgonly > uvmexp.swpages) {
+ panic("uvmexp.swpgonly botch");
+ }
+#endif
+ if (anon == NULL || uvmexp.swpgonly == uvmexp.swpages) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
uvmexp.fltnoanon++;
- /* XXX: OUT OF VM, ??? */
return (KERN_RESOURCE_SHORTAGE);
}
+
uvmexp.fltnoram++;
uvm_wait("flt_noram3"); /* out of RAM, wait for more */
goto ReFault;
@@ -1207,6 +1212,7 @@
if (fault_type == VM_FAULT_WIRE) {
uvm_pagewire(pg);
+ uvm_anon_dropswap(anon);
} else {
/* activate it */
uvm_pageactivate(pg);
Home |
Main Index |
Thread Index |
Old Index