Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm uvm_fault: Split "neighbor" fault and loan handling ...



details:   https://anonhg.NetBSD.org/src/rev/2062fc533ad7
branches:  trunk
changeset: 751361:2062fc533ad7
user:      uebayasi <uebayasi%NetBSD.org@localhost>
date:      Tue Feb 02 04:35:35 2010 +0000

description:
uvm_fault: Split "neighbor" fault and loan handling into functions.

diffstat:

 sys/uvm/uvm_fault.c |  146 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 113 insertions(+), 33 deletions(-)

diffs (truncated from 318 to 300 lines):

diff -r a8e1510c46e5 -r 2062fc533ad7 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c       Tue Feb 02 04:28:55 2010 +0000
+++ b/sys/uvm/uvm_fault.c       Tue Feb 02 04:35:35 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_fault.c,v 1.150 2010/02/02 01:54:48 uebayasi Exp $ */
+/*     $NetBSD: uvm_fault.c,v 1.151 2010/02/02 04:35:35 uebayasi Exp $ */
 
 /*
  *
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.150 2010/02/02 01:54:48 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.151 2010/02/02 04:35:35 uebayasi Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -1002,6 +1002,15 @@
        return 0;
 }
 
+static inline void
+uvm_fault_upper_lookup1(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       bool shadowed);
+static void
+uvm_fault_upper_lookup_neighbor(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       vaddr_t currva, struct vm_anon *anon);
+
 static int
 uvm_fault_upper_lookup(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
@@ -1024,8 +1033,6 @@
        currva = flt->startva;
        shadowed = false;
        for (lcv = 0 ; lcv < flt->npages ; lcv++, currva += PAGE_SIZE) {
-               struct vm_anon *anon;
-
                /*
                 * dont play with VAs that are already mapped
                 * except for center)
@@ -1051,9 +1058,22 @@
                pages[lcv] = PGO_DONTCARE;
                if (lcv == flt->centeridx) {            /* save center for later! */
                        shadowed = true;
-                       continue;
+               } else {
+                       uvm_fault_upper_lookup_neighbor(ufi, flt, currva, anons[lcv]);
                }
-               anon = anons[lcv];
+       }
+
+       uvm_fault_upper_lookup1(ufi, flt, shadowed);
+
+       return 0;
+}
+
+static void
+uvm_fault_upper_lookup_neighbor(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       vaddr_t currva, struct vm_anon *anon)
+{
+
                mutex_enter(&anon->an_lock);
 
                /* ignore loaned and busy pages */
@@ -1085,7 +1105,19 @@
 uvm_fault_upper_lookup_enter_done:
                pmap_update(ufi->orig_map->pmap);
                mutex_exit(&anon->an_lock);
-       }
+}
+
+static inline void
+uvm_fault_upper_lookup1(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       bool shadowed)
+{
+#ifdef DIAGNOSTIC
+       struct vm_amap *amap = ufi->entry->aref.ar_amap;
+#endif
+#ifdef UVMHIST
+       struct uvm_object *uobj = ufi->entry->object.uvm_obj;
+#endif
 
        /* locked: maps(read), amap(if there) */
        KASSERT(amap == NULL || mutex_owned(&amap->am_l));
@@ -1100,8 +1132,6 @@
         * XXX Actually, that is bad; pmap_enter() should just fail in that
         * XXX case.  --thorpej
         */
-
-       return 0;
 }
 
 static int
@@ -1152,6 +1182,10 @@
        return error;
 }
 
+static void uvm_fault_lower_generic_lookup_neighbor(
+    struct uvm_faultinfo *, struct uvm_faultctx *,
+    vaddr_t, struct vm_page *);
+
 static int
 uvm_fault_lower_generic(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
@@ -1210,7 +1244,6 @@
        currva = flt->startva;
        for (lcv = 0; lcv < flt->npages; lcv++, currva += PAGE_SIZE) {
                struct vm_page *curpg;
-               bool readonly;
 
                curpg = pages[lcv];
                if (curpg == NULL || curpg == PGO_DONTCARE) {
@@ -1228,8 +1261,20 @@
                        UVMHIST_LOG(maphist, "  got uobjpage "
                            "(0x%x) with locked get",
                            curpg, 0,0,0);
-                       continue;
-               }
+               } else
+                       uvm_fault_lower_generic_lookup_neighbor(ufi, flt,
+                           currva, curpg);
+       }
+       pmap_update(ufi->orig_map->pmap);
+       return 0;
+}
+
+static void
+uvm_fault_lower_generic_lookup_neighbor(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       vaddr_t currva, struct vm_page *curpg)
+{
+               bool readonly;
 
                /*
                 * calling pgo_get with PGO_LOCKED returns us pages which
@@ -1273,9 +1318,6 @@
 
                curpg->flags &= ~(PG_BUSY);
                UVM_PAGE_OWN(curpg, NULL);
-       }
-       pmap_update(ufi->orig_map->pmap);
-       return 0;
 }
 
 static int
@@ -1420,12 +1462,17 @@
 }
 
 static int
+uvm_fault_upper_loan_break(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_anon *anon, struct uvm_object **ruobj);
+
+static int
 uvm_fault_upper_loan(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
        struct vm_anon *anon, struct uvm_object **ruobj)
 {
        struct vm_amap * const amap = ufi->entry->aref.ar_amap;
-       struct uvm_object *uobj = *ruobj;
+       int error = 0;
 
        if (!flt->cow_now) {
 
@@ -1452,14 +1499,29 @@
 
                /* >1 case is already ok */
                if (anon->an_ref == 1) {
+                       error = uvm_fault_upper_loan_break(ufi, flt, anon, ruobj);
+                       if (error != 0) {
+                               uvmfault_unlockall(ufi, amap, *ruobj, anon);
+                               uvm_wait("flt_noram2");
+                               return ERESTART;
+                       }
+               }
+       }
+       return error;
+}
+
+/* XXXUEBS consider to move this elsewhere */
+static int
+uvm_fault_upper_loan_break(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_anon *anon, struct uvm_object **ruobj)
+{
                        struct vm_page *pg;
 
                        /* get new un-owned replacement page */
                        pg = uvm_pagealloc(NULL, 0, NULL, 0);
                        if (pg == NULL) {
-                               uvmfault_unlockall(ufi, amap, uobj, anon);
-                               uvm_wait("flt_noram2");
-                               return ERESTART;
+                               return ENOMEM;
                        }
 
                        /*
@@ -1477,7 +1539,7 @@
                        /* in case we owned */
                        anon->an_page->pqflags &= ~PQ_ANON;
 
-                       if (uobj) {
+                       if (*ruobj) {
                                /* if we were receiver of loan */
                                anon->an_page->loan_count--;
                        } else {
@@ -1488,8 +1550,8 @@
                                uvm_pagedequeue(anon->an_page);
                        }
 
-                       if (uobj) {
-                               mutex_exit(&uobj->vmobjlock);
+                       if (*ruobj) {
+                               mutex_exit(&(*ruobj)->vmobjlock);
                                *ruobj = NULL;
                        }
 
@@ -1505,10 +1567,8 @@
                        UVM_PAGE_OWN(pg, NULL);
 
                        /* done! */
-               }     /* ref == 1 */
-       }       /* write fault */
 
-       return 0;
+                       return 0;
 }
 
 static int
@@ -1691,7 +1751,7 @@
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
        struct vm_page **ruobjpage);
 static int
-uvm_fault_lower_generic_uobjpage(
+uvm_fault_lower_generic3(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
        struct vm_page *uobjpage, bool promote);
 static int
@@ -1771,7 +1831,7 @@
                if (error != 0)
                        return error;
        }
-       return uvm_fault_lower_generic_uobjpage(ufi, flt, uobjpage, promote);
+       return uvm_fault_lower_generic3(ufi, flt, uobjpage, promote);
 }
 
 static int
@@ -1897,7 +1957,7 @@
 }
 
 int
-uvm_fault_lower_generic_uobjpage(
+uvm_fault_lower_generic3(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
        struct vm_page *uobjpage, bool promote)
 {
@@ -1935,12 +1995,16 @@
        return error;
 }
 
+static int
+uvm_fault_lower_generic_direct_loan(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page **rpg, struct vm_page **ruobjpage);
+
 int
 uvm_fault_lower_generic_direct(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
        struct vm_page *uobjpage)
 {
-       struct vm_amap * const amap = ufi->entry->aref.ar_amap;
        struct uvm_object * const uobj = ufi->entry->object.uvm_obj;
        struct vm_page *pg;
 
@@ -1967,6 +2031,23 @@
         */
 
        if (uobjpage->loan_count) {
+               uvm_fault_lower_generic_direct_loan(ufi, flt, &pg, &uobjpage);
+       }
+       KASSERT(pg == uobjpage);
+
+       return uvm_fault_lower_generic_enter(ufi, flt, uobj, NULL, pg, uobjpage);
+}
+
+static int
+uvm_fault_lower_generic_direct_loan(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page **rpg, struct vm_page **ruobjpage)
+{
+               struct vm_amap * const amap = ufi->entry->aref.ar_amap;
+               struct uvm_object * const uobj = ufi->entry->object.uvm_obj;
+               struct vm_page *pg;
+               struct vm_page *uobjpage = *ruobjpage;
+



Home | Main Index | Thread Index | Old Index