Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm several changes prompted by loaning problems:



details:   https://anonhg.NetBSD.org/src/rev/b97c37e181d8
branches:  trunk
changeset: 517080:b97c37e181d8
user:      chs <chs%NetBSD.org@localhost>
date:      Tue Nov 06 08:07:49 2001 +0000

description:
several changes prompted by loaning problems:
 - fix the loaned case in uvm_pagefree().
 - redo uvmexp.swpgonly accounting to work with page loaning.
   add an assertion before each place we adjust uvmexp.swpgonly.
 - fix uvm_km_pgremove() to always free any swap space associated with
   the range being removed.
 - get rid of UVM_LOAN_WIRED flag.  instead, we just make sure that
   pages loaned to the kernel are never on the page queues.
   this allows us to assert that pages are not loaned and wired
   at the same time.
 - add yet more assertions.

diffstat:

 sys/uvm/uvm_anon.c    |   17 +-
 sys/uvm/uvm_aobj.c    |    9 +-
 sys/uvm/uvm_km.c      |   61 +++-------
 sys/uvm/uvm_loan.c    |  296 ++++++++++++++++++++++++-------------------------
 sys/uvm/uvm_loan.h    |    9 +-
 sys/uvm/uvm_page.c    |   50 ++++---
 sys/uvm/uvm_pager.c   |   25 ++-
 sys/uvm/uvm_pdaemon.c |    8 +-
 8 files changed, 228 insertions(+), 247 deletions(-)

diffs (truncated from 1039 to 300 lines):

diff -r b9b73338db12 -r b97c37e181d8 sys/uvm/uvm_anon.c
--- a/sys/uvm/uvm_anon.c        Tue Nov 06 07:30:14 2001 +0000
+++ b/sys/uvm/uvm_anon.c        Tue Nov 06 08:07:49 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_anon.c,v 1.19 2001/10/21 00:04:42 chs Exp $        */
+/*     $NetBSD: uvm_anon.c,v 1.20 2001/11/06 08:07:49 chs Exp $        */
 
 /*
  *
@@ -181,6 +181,7 @@
  * => anon must be unlocked and have a zero reference count.
  * => we may lock the pageq's.
  */
+
 void
 uvm_anfree(anon)
        struct vm_anon *anon;
@@ -254,6 +255,13 @@
                                    "freed now!", anon, pg, 0, 0);
                }
        }
+       if (pg == NULL && anon->an_swslot != 0) {
+               /* this page is no longer only in swap. */
+               simple_lock(&uvm.swap_data_lock);
+               KASSERT(uvmexp.swpgonly > 0);
+               uvmexp.swpgonly--;
+               simple_unlock(&uvm.swap_data_lock);
+       }
 
        /*
         * free any swap resources.
@@ -292,13 +300,6 @@
                    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);
-       }
 }
 
 /*
diff -r b9b73338db12 -r b97c37e181d8 sys/uvm/uvm_aobj.c
--- a/sys/uvm/uvm_aobj.c        Tue Nov 06 07:30:14 2001 +0000
+++ b/sys/uvm/uvm_aobj.c        Tue Nov 06 08:07:49 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_aobj.c,v 1.46 2001/09/15 20:36:45 chs Exp $        */
+/*     $NetBSD: uvm_aobj.c,v 1.47 2001/11/06 08:07:49 chs Exp $        */
 
 /*
  * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -454,6 +454,7 @@
         */
 
        simple_lock(&uvm.swap_data_lock);
+       KASSERT(uvmexp.swpgonly >= swpgonlydelta);
        uvmexp.swpgonly -= swpgonlydelta;
        simple_unlock(&uvm.swap_data_lock);
 }
@@ -963,9 +964,9 @@
                                    NULL, UVM_PGA_ZERO);
                                if (ptmp) {
                                        /* new page */
-                                       ptmp->flags &= ~(PG_BUSY|PG_FAKE);
+                                       ptmp->flags &= ~(PG_FAKE);
                                        ptmp->pqflags |= PQ_AOBJ;
-                                       UVM_PAGE_OWN(ptmp, NULL);
+                                       goto gotpage;
                                }
                        }
 
@@ -989,6 +990,7 @@
                        /* caller must un-busy this page */
                        ptmp->flags |= PG_BUSY;
                        UVM_PAGE_OWN(ptmp, "uao_get1");
+gotpage:
                        pps[lcv] = ptmp;
                        gotpages++;
                }
@@ -1215,7 +1217,6 @@
        }
 }
 
-
 /*
  * page in every page in every aobj that is paged-out to a range of swslots.
  *
diff -r b9b73338db12 -r b97c37e181d8 sys/uvm/uvm_km.c
--- a/sys/uvm/uvm_km.c  Tue Nov 06 07:30:14 2001 +0000
+++ b/sys/uvm/uvm_km.c  Tue Nov 06 08:07:49 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_km.c,v 1.52 2001/09/15 20:36:46 chs Exp $  */
+/*     $NetBSD: uvm_km.c,v 1.53 2001/11/06 08:07:50 chs Exp $  */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -178,7 +178,7 @@
                                 VM_MIN_KERNEL_ADDRESS, UAO_FLAG_KERNOBJ);
 
        /*
-        * init the map and reserve allready allocated kernel space
+        * init the map and reserve already allocated kernel space
         * before installing.
         */
 
@@ -271,27 +271,18 @@
        struct uvm_object *uobj;
        vaddr_t start, end;
 {
-       boolean_t by_list;
-       struct vm_page *pg, *nextpg;
+       struct vm_page *pg;
        voff_t curoff, nextoff;
+       int swpgonlydelta = 0;
        UVMHIST_FUNC("uvm_km_pgremove"); UVMHIST_CALLED(maphist);
 
        KASSERT(uobj->pgops == &aobj_pager);
        simple_lock(&uobj->vmobjlock);
 
-       /* choose cheapest traversal */
-       by_list = (uobj->uo_npages <=
-            ((end - start) >> PAGE_SHIFT) * UVM_PAGE_HASH_PENALTY);
-       if (by_list)
-               goto loop_by_list;
-
        for (curoff = start; curoff < end; curoff = nextoff) {
                nextoff = curoff + PAGE_SIZE;
                pg = uvm_pagelookup(uobj, curoff);
-               if (pg == NULL) {
-                       continue;
-               }
-               if (pg->flags & PG_BUSY) {
+               if (pg != NULL && pg->flags & PG_BUSY) {
                        pg->flags |= PG_WANTED;
                        UVM_UNLOCK_AND_WAIT(pg, &uobj->vmobjlock, 0,
                                    "km_pgrm", 0);
@@ -304,39 +295,23 @@
                 * free the swap slot, then the page.
                 */
 
+               if (pg == NULL &&
+                   uao_find_swslot(uobj, curoff >> PAGE_SHIFT) != 0) {
+                       swpgonlydelta++;
+               }
                uao_dropswap(uobj, curoff >> PAGE_SHIFT);
-               uvm_lock_pageq();
-               uvm_pagefree(pg);
-               uvm_unlock_pageq();
+               if (pg != NULL) {
+                       uvm_lock_pageq();
+                       uvm_pagefree(pg);
+                       uvm_unlock_pageq();
+               }
        }
        simple_unlock(&uobj->vmobjlock);
-       return;
 
-loop_by_list:
-       for (pg = TAILQ_FIRST(&uobj->memq); pg != NULL; pg = nextpg) {
-               nextpg = TAILQ_NEXT(pg, listq);
-               if (pg->offset < start || pg->offset >= end) {
-                       continue;
-               }
-               if (pg->flags & PG_BUSY) {
-                       pg->flags |= PG_WANTED;
-                       UVM_UNLOCK_AND_WAIT(pg, &uobj->vmobjlock, 0,
-                                   "km_pgrm", 0);
-                       simple_lock(&uobj->vmobjlock);
-                       nextpg = TAILQ_FIRST(&uobj->memq);
-                       continue;
-               }
-
-               /*
-                * free the swap slot, then the page.
-                */
-
-               uao_dropswap(uobj, pg->offset >> PAGE_SHIFT);
-               uvm_lock_pageq();
-               uvm_pagefree(pg);
-               uvm_unlock_pageq();
-       }
-       simple_unlock(&uobj->vmobjlock);
+       simple_lock(&uvm.swap_data_lock);
+       KASSERT(uvmexp.swpgonly >= swpgonlydelta);
+       uvmexp.swpgonly -= swpgonlydelta;
+       simple_unlock(&uvm.swap_data_lock);
 }
 
 
diff -r b9b73338db12 -r b97c37e181d8 sys/uvm/uvm_loan.c
--- a/sys/uvm/uvm_loan.c        Tue Nov 06 07:30:14 2001 +0000
+++ b/sys/uvm/uvm_loan.c        Tue Nov 06 08:07:49 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_loan.c,v 1.33 2001/09/22 05:58:04 jdolecek Exp $   */
+/*     $NetBSD: uvm_loan.c,v 1.34 2001/11/06 08:07:50 chs Exp $        */
 
 /*
  *
@@ -110,8 +110,8 @@
 static int     uvm_loanuobj __P((struct uvm_faultinfo *, void ***,
                                int, vaddr_t));
 static int     uvm_loanzero __P((struct uvm_faultinfo *, void ***, int));
-static void    uvm_unloananon __P((struct vm_anon **, int, int));
-static void    uvm_unloanpage __P((struct vm_page **, int, int));
+static void    uvm_unloananon __P((struct vm_anon **, int));
+static void    uvm_unloanpage __P((struct vm_page **, int));
 
 
 /*
@@ -176,21 +176,22 @@
                } else if (UVM_ET_ISCOPYONWRITE(ufi->entry)) {
                        rv = uvm_loanzero(ufi, output, flags);
                } else {
-                       rv = -1;        /* null map entry... fail now */
+                       rv = -1;
                }
                /* locked: if (rv > 0) => map, amap, uobj  [o.w. unlocked] */
 
                /* total failure */
                if (rv < 0)
-                       return(-1);             /* everything unlocked */
+                       return (-1);
 
                /* relock failed, need to do another lookup */
                if (rv == 0)
-                       return(result);         /* everything unlocked */
+                       return (result);
 
                /*
                 * got it... advance to next page
                 */
+
                result++;
                togo -= PAGE_SIZE;
                curaddr += PAGE_SIZE;
@@ -199,12 +200,13 @@
        /*
         * unlock what we locked, unlock the maps and return
         */
+
        if (aref->ar_amap)
                amap_unlock(aref->ar_amap);
        if (uobj)
                simple_unlock(&uobj->vmobjlock);
        uvmfault_unlockmaps(ufi, FALSE);
-       return(result);
+       return (result);
 }
 
 /*
@@ -224,15 +226,15 @@
  */
 
 int
-uvm_loan(map, start, len, result, flags)
+uvm_loan(map, start, len, v, flags)
        struct vm_map *map;
        vaddr_t start;
        vsize_t len;
-       void **result;
+       void *v;
        int flags;
 {
        struct uvm_faultinfo ufi;
-       void **output;
+       void **result, **output;
        int rv, error;
 
        /*
@@ -244,10 +246,10 @@
        KASSERT((map->flags & VM_MAP_INTRSAFE) == 0);
 
        /*
-        * "output" is a pointer to the current place to put the loaned
-        * page...
+        * "output" is a pointer to the current place to put the loaned page.
         */
 
+       result = v;
        output = &result[0];    /* start at the beginning ... */
 
        /*
@@ -277,6 +279,7 @@
                /*
                 * map now locked.  now do the loanout...
                 */
+
                rv = uvm_loanentry(&ufi, &output, flags);
                if (rv < 0) {
                        /* all unlocked due to error */
@@ -291,31 +294,29 @@
                 *         smarter code (but it only happens on map entry 
                 *         boundaries, so it isn't that bad).
                 */
+
                if (rv) {
                        rv <<= PAGE_SHIFT;



Home | Main Index | Thread Index | Old Index