Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm Page scanner improvements, behavior is actually a bi...



details:   https://anonhg.NetBSD.org/src/rev/98ca597307f5
branches:  trunk
changeset: 503019:98ca597307f5
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sun Jan 28 23:30:42 2001 +0000

description:
Page scanner improvements, behavior is actually a bit more like
Mach VM's now.  Specific changes:
- Pages now need not have all of their mappings removed before being
  put on the inactive list.  They only need to have the "referenced"
  attribute cleared.  This makes putting pages onto the inactive list
  much more efficient.  In order to eliminate redundant clearings of
  "refrenced", callers of uvm_pagedeactivate() must now do this
  themselves.
- When checking the "modified" attribute for a page (for clearing
  PG_CLEAN), make sure to only do it if PG_CLEAN is currently set on
  the page (saves a potentially expensive pmap operation).
- When scanning the inactive list, if a page is referenced, reactivate
  it (this part was actually added in uvm_pdaemon.c,v 1.27).  This
  now works properly now that pages on the inactive list are allowed to
  have mappings.
- When scanning the inactive list and considering a page for freeing,
  remove all mappings, and then check the "modified" attribute if the
  page is marked PG_CLEAN.
- When scanning the active list, if the page was referenced since its
  last sweep by the scanner, don't deactivate it.  (This part was
  actually added in uvm_pdaemon.c,v 1.28.)

These changes greatly improve interactive performance during
moderate to high memory and I/O load.

diffstat:

 sys/uvm/uvm_anon.c    |   3 +--
 sys/uvm/uvm_aobj.c    |   7 ++-----
 sys/uvm/uvm_fault.c   |   4 ++--
 sys/uvm/uvm_map.c     |   6 ++----
 sys/uvm/uvm_page_i.h  |  16 ++++++++++++----
 sys/uvm/uvm_pager.c   |  43 +++++++++++++++++++++----------------------
 sys/uvm/uvm_pdaemon.c |  17 ++++++++++-------
 sys/uvm/uvm_vnode.c   |   9 +++++----
 8 files changed, 55 insertions(+), 50 deletions(-)

diffs (283 lines):

diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_anon.c
--- a/sys/uvm/uvm_anon.c        Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_anon.c        Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_anon.c,v 1.13 2001/01/23 02:27:39 thorpej Exp $    */
+/*     $NetBSD: uvm_anon.c,v 1.14 2001/01/28 23:30:42 thorpej Exp $    */
 
 /*
  *
@@ -526,7 +526,6 @@
         */
 
        pmap_clear_reference(pg);
-       pmap_page_protect(pg, VM_PROT_NONE);
        uvm_lock_pageq();
        uvm_pagedeactivate(pg);
        uvm_unlock_pageq();
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_aobj.c
--- a/sys/uvm/uvm_aobj.c        Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_aobj.c        Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_aobj.c,v 1.37 2000/11/25 06:27:59 chs Exp $        */
+/*     $NetBSD: uvm_aobj.c,v 1.38 2001/01/28 23:30:42 thorpej Exp $    */
 
 /*
  * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -882,10 +882,8 @@
                            pp->wire_count != 0)
                                continue;
 
-                       /* zap all mappings for the page. */
-                       pmap_page_protect(pp, VM_PROT_NONE);
-
                        /* ...and deactivate the page. */
+                       pmap_clear_reference(pp);
                        uvm_pagedeactivate(pp);
 
                        continue;
@@ -1543,7 +1541,6 @@
         * deactivate the page (to put it on a page queue).
         */
        pmap_clear_reference(pg);
-       pmap_page_protect(pg, VM_PROT_NONE);
        uvm_lock_pageq();
        uvm_pagedeactivate(pg);
        uvm_unlock_pageq();
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c       Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_fault.c       Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_fault.c,v 1.54 2001/01/23 02:27:39 thorpej Exp $   */
+/*     $NetBSD: uvm_fault.c,v 1.55 2001/01/28 23:30:43 thorpej Exp $   */
 
 /*
  *
@@ -205,7 +205,7 @@
                if (pg && (pg->flags & PG_BUSY) == 0 && pg->loan_count == 0) {
                        uvm_lock_pageq();
                        if (pg->wire_count == 0) {
-                               pmap_page_protect(pg, VM_PROT_NONE);
+                               pmap_clear_reference(pg);
                                uvm_pagedeactivate(pg);
                        }
                        uvm_unlock_pageq();
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_map.c Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.88 2001/01/14 02:10:01 thorpej Exp $     */
+/*     $NetBSD: uvm_map.c,v 1.89 2001/01/28 23:30:44 thorpej Exp $     */
 
 /* 
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -2566,10 +2566,8 @@
                                }
                                KASSERT(pg->uanon == anon);
 
-                               /* zap all mappings for the page. */
-                               pmap_page_protect(pg, VM_PROT_NONE);
-
                                /* ...and deactivate the page. */
+                               pmap_clear_reference(pg);
                                uvm_pagedeactivate(pg);
 
                                uvm_unlock_pageq();
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_page_i.h
--- a/sys/uvm/uvm_page_i.h      Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_page_i.h      Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_page_i.h,v 1.15 2001/01/14 02:10:02 thorpej Exp $  */
+/*     $NetBSD: uvm_page_i.h,v 1.16 2001/01/28 23:30:45 thorpej Exp $  */
 
 /* 
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -193,11 +193,12 @@
 }
 
 /*
- * uvm_pagedeactivate: deactivate page -- no pmaps have access to page
+ * uvm_pagedeactivate: deactivate 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
@@ -217,8 +218,15 @@
                        TAILQ_INSERT_TAIL(&uvm.page_inactive_obj, pg, pageq);
                pg->pqflags |= PQ_INACTIVE;
                uvmexp.inactive++;
-               pmap_clear_reference(pg);
-               if (pmap_is_modified(pg))
+
+               /*
+                * update the "clean" bit.  this isn't 100%
+                * accurate, and doesn't have to be.  we'll
+                * re-sync it after we zap all mappings when
+                * scanning the inactive list.
+                */
+               if ((pg->flags & PG_CLEAN) != 0 &&
+                   pmap_is_modified(pg))
                        pg->flags &= ~PG_CLEAN;
        }
 }
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_pager.c
--- a/sys/uvm/uvm_pager.c       Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_pager.c       Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_pager.c,v 1.38 2000/12/09 23:26:27 chs Exp $       */
+/*     $NetBSD: uvm_pager.c,v 1.39 2001/01/28 23:30:45 thorpej Exp $   */
 
 /*
  *
@@ -315,11 +315,6 @@
        /*
         * 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++) {
@@ -333,24 +328,28 @@
                        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;
+                       }
 
-                               /* 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;
+                       /*
+                        * 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;
-                               }
+                               /* now checked */
+                               pclust->flags |= PG_CLEANCHK;
                        }
 
                        /* is page available for cleaning and does it need it */
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_pdaemon.c
--- a/sys/uvm/uvm_pdaemon.c     Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_pdaemon.c     Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_pdaemon.c,v 1.28 2001/01/25 00:24:48 thorpej Exp $ */
+/*     $NetBSD: uvm_pdaemon.c,v 1.29 2001/01/28 23:30:46 thorpej Exp $ */
 
 /* 
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -81,8 +81,6 @@
 
 #include <uvm/uvm.h>
 
-extern struct uvm_pagerops uvm_vnodeops;
-
 /*
  * UVMPD_NUMDIRTYREACTS is how many dirty pages the pagedeamon will reactivate
  * in a pass thru the inactive list when swap is full.  the value should be
@@ -514,7 +512,7 @@
                                uobj = p->uobject;
                                KASSERT(uobj != NULL);
                                if (vnode_only &&
-                                   uobj->pgops != &uvm_vnodeops) {
+                                   UVM_OBJ_IS_VNODE(uobj) == 0) {
                                        uvm_pageactivate(p);
                                        continue;
                                }
@@ -533,10 +531,16 @@
 
                        /*
                         * we now have the object and the page queues locked.
-                        * the page is not busy.   if the page is clean we
-                        * can free it now and continue.
+                        * 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.
                         */
 
+                       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 */
@@ -1105,7 +1109,6 @@
 
                if (inactive_shortage > 0 &&
                    pmap_clear_reference(p) == FALSE) {
-                       pmap_page_protect(p, VM_PROT_NONE);
                        /* no need to check wire_count as pg is "active" */
                        uvm_pagedeactivate(p);
                        uvmexp.pddeact++;
diff -r e8f29e9b2ca7 -r 98ca597307f5 sys/uvm/uvm_vnode.c
--- a/sys/uvm/uvm_vnode.c       Sun Jan 28 22:31:53 2001 +0000
+++ b/sys/uvm/uvm_vnode.c       Sun Jan 28 23:30:42 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_vnode.c,v 1.41 2001/01/08 06:21:13 chs Exp $       */
+/*     $NetBSD: uvm_vnode.c,v 1.42 2001/01/28 23:30:47 thorpej Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -540,7 +540,8 @@
                         */
                        if ((pp->flags & PG_CLEAN) != 0 && 
                            (flags & PGO_FREE) != 0 &&
-                           (pp->pqflags & PQ_ACTIVE) != 0)
+                           /* XXX ACTIVE|INACTIVE test unnecessary? */
+                           (pp->pqflags & (PQ_ACTIVE|PQ_INACTIVE)) != 0)
                                pmap_page_protect(pp, VM_PROT_NONE);
                        if ((pp->flags & PG_CLEAN) != 0 &&
                            pmap_is_modified(pp))
@@ -564,7 +565,7 @@
                                if ((pp->pqflags & PQ_INACTIVE) == 0 &&
                                    (pp->flags & PG_BUSY) == 0 &&
                                    pp->wire_count == 0) {
-                                       pmap_page_protect(pp, VM_PROT_NONE);
+                                       pmap_clear_reference(pp);
                                        uvm_pagedeactivate(pp);
                                }
 
@@ -756,7 +757,7 @@
                                if ((pp->pqflags & PQ_INACTIVE) == 0 &&
                                    (pp->flags & PG_BUSY) == 0 &&
                                    pp->wire_count == 0) {
-                                       pmap_page_protect(ptmp, VM_PROT_NONE);
+                                       pmap_clear_reference(ptmp);
                                        uvm_pagedeactivate(ptmp);
                                }
                        } else if (flags & PGO_FREE) {



Home | Main Index | Thread Index | Old Index