Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm Free pages in batch instead of taking uvm_pageqlock ...



details:   https://anonhg.NetBSD.org/src/rev/54e4755663ef
branches:  trunk
changeset: 465668:54e4755663ef
user:      ad <ad%NetBSD.org@localhost>
date:      Sun Dec 01 17:02:50 2019 +0000

description:
Free pages in batch instead of taking uvm_pageqlock for each one.

diffstat:

 sys/uvm/uvm_anon.c |  67 ++++++++++++++++++++++++++++++++---------------------
 1 files changed, 40 insertions(+), 27 deletions(-)

diffs (147 lines):

diff -r 187e2edc29b3 -r 54e4755663ef sys/uvm/uvm_anon.c
--- a/sys/uvm/uvm_anon.c        Sun Dec 01 16:44:11 2019 +0000
+++ b/sys/uvm/uvm_anon.c        Sun Dec 01 17:02:50 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_anon.c,v 1.65 2019/12/01 14:40:31 ad Exp $ */
+/*     $NetBSD: uvm_anon.c,v 1.66 2019/12/01 17:02:50 ad Exp $ */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.65 2019/12/01 14:40:31 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.66 2019/12/01 17:02:50 ad Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -94,7 +94,7 @@
 }
 
 /*
- * uvm_anon_dispose: free any resident page or swap resources of anon.
+ * uvm_anon_dispose: break loans and remove pmap mapping
  *
  * => anon must be removed from the amap (if anon was in an amap).
  * => amap must be locked; we may drop and re-acquire the lock here.
@@ -110,17 +110,6 @@
        KASSERT(mutex_owned(anon->an_lock));
 
        /*
-        * If there is a resident page and it is loaned, then anon may not
-        * own it.  Call out to uvm_anon_lockloanpg() to identify and lock
-        * the real owner of the page.
-        */
-
-       if (pg && pg->loan_count) {
-               KASSERT(anon->an_lock != NULL);
-               pg = uvm_anon_lockloanpg(anon);
-       }
-
-       /*
         * Dispose the page, if it is resident.
         */
 
@@ -128,6 +117,16 @@
                KASSERT(anon->an_lock != NULL);
 
                /*
+                * If there is a resident page and it is loaned, then anon
+                * may not own it.  Call out to uvm_anon_lockloanpg() to
+                * identify and lock the real owner of the page.
+                */
+
+               if (pg->loan_count) {
+                       pg = uvm_anon_lockloanpg(anon);
+               }
+
+               /*
                 * If the page is owned by a UVM object (now locked),
                 * then kill the loan on the page rather than free it,
                 * and release the object lock.
@@ -160,12 +159,6 @@
                                mutex_obj_hold(anon->an_lock);
                                return false;
                        }
-                       mutex_enter(&uvm_pageqlock);
-                       uvm_pagefree(pg);
-                       mutex_exit(&uvm_pageqlock);
-                       UVMHIST_LOG(maphist, "anon 0x%#jx, page 0x%#jx: "
-                           "freed now!", (uintptr_t)anon, (uintptr_t)pg,
-                           0, 0);
                }
        }
 
@@ -177,12 +170,6 @@
        }
 #endif
 
-       /*
-        * Free any swap resources, leave a page replacement hint.
-        */
-
-       uvm_anon_dropswap(anon);
-       uvmpdpol_anfree(anon);
        UVMHIST_LOG(maphist,"<- done!",0,0,0,0);
        return true;
 }
@@ -196,6 +183,10 @@
 uvm_anon_free(struct vm_anon *anon)
 {
 
+#if defined(VMSWAP)
+       /* Free any dangling swap slot. */
+       uvm_anon_dropswap(anon);
+#endif
        KASSERT(anon->an_ref == 0);
        KASSERT(anon->an_lock == NULL);
        KASSERT(anon->an_page == NULL);
@@ -208,15 +199,23 @@
 /*
  * uvm_anon_freelst: free a linked list of anon structures.
  *
- * => anon must be locked, we will unlock it.
+ * => amap must be locked, we will unlock it.
  */
 void
 uvm_anon_freelst(struct vm_amap *amap, struct vm_anon *anonlst)
 {
        struct vm_anon *anon;
        struct vm_anon **anonp = &anonlst;
+       struct vm_page *pg;
 
        KASSERT(mutex_owned(amap->am_lock));
+
+       if (anonlst == NULL) {
+               amap_unlock(amap);
+               return;
+       }
+
+       /* Break loans and hardware mappings.  Defer release of busy pages. */
        while ((anon = *anonp) != NULL) {
                if (!uvm_anon_dispose(anon)) {
                        /* Do not free this anon. */
@@ -227,8 +226,22 @@
                        anonp = &anon->an_link;
                }
        }
+
+       /* Free pages and leave a page replacement hint. */
+       mutex_enter(&uvm_pageqlock);
+       for (anon = anonlst; anon != NULL; anon = anon->an_link) {
+               UVMHIST_LOG(maphist, "anon 0x%#jx, page 0x%#jx: "
+                   "releasing now!", (uintptr_t)anon,
+                   (uintptr_t)anon->an_page, 0, 0);
+               if ((pg = anon->an_page) != NULL) {
+                       uvm_pagefree(pg);
+               }
+               uvmpdpol_anfree(anon);
+       }
+       mutex_exit(&uvm_pageqlock);
        amap_unlock(amap);
 
+       /* Free swap space, pages and vm_anon. */
        while (anonlst) {
                anon = anonlst->an_link;
                /* Note: clears an_ref as well. */



Home | Main Index | Thread Index | Old Index