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