Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm More split.



details:   https://anonhg.NetBSD.org/src/rev/fc038f65e856
branches:  trunk
changeset: 751353:fc038f65e856
user:      uebayasi <uebayasi%NetBSD.org@localhost>
date:      Mon Feb 01 16:08:27 2010 +0000

description:
More split.

diffstat:

 sys/uvm/uvm_fault.c |  271 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 234 insertions(+), 37 deletions(-)

diffs (truncated from 471 to 300 lines):

diff -r 2e982966328d -r fc038f65e856 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c       Mon Feb 01 12:58:04 2010 +0000
+++ b/sys/uvm/uvm_fault.c       Mon Feb 01 16:08:27 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_fault.c,v 1.147 2010/02/01 11:58:39 uebayasi Exp $ */
+/*     $NetBSD: uvm_fault.c,v 1.148 2010/02/01 16:08:27 uebayasi Exp $ */
 
 /*
  *
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.147 2010/02/01 11:58:39 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.148 2010/02/01 16:08:27 uebayasi Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -713,7 +713,6 @@
     struct uvm_faultinfo *, struct uvm_faultctx *,
     struct vm_anon **, struct vm_page **);
 static uvm_fault_upper_subfunc_t uvm_fault_upper_lookup;
-static uvm_fault_upper_subfunc_t uvm_fault_upper;
 typedef int uvm_fault_lower_subfunc_t(
     struct uvm_faultinfo *, struct uvm_faultctx *,
     struct vm_page **);
@@ -721,8 +720,15 @@
 static uvm_fault_lower_subfunc_t uvm_fault_lower_special;
 static uvm_fault_lower_subfunc_t uvm_fault_lower_generic_lookup;
 static uvm_fault_lower_subfunc_t uvm_fault_lower_generic;
-static uvm_fault_lower_subfunc_t uvm_fault_lower_generic1;
-static uvm_fault_lower_subfunc_t uvm_fault_lower_generic2;
+static int uvm_fault_upper(
+    struct uvm_faultinfo *, struct uvm_faultctx *,
+    struct vm_anon **);
+static int uvm_fault_lower_generic1(
+    struct uvm_faultinfo *, struct uvm_faultctx *,
+    struct vm_page *);
+static int uvm_fault_lower_generic2(
+    struct uvm_faultinfo *, struct uvm_faultctx *,
+    struct vm_page *);
 
 int
 uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr,
@@ -773,7 +779,7 @@
                        continue;
 
                if (pages[flt.centeridx] == PGO_DONTCARE)
-                       error = uvm_fault_upper(&ufi, &flt, anons, pages);
+                       error = uvm_fault_upper(&ufi, &flt, anons);
                else
                        error = uvm_fault_lower(&ufi, &flt, pages);
        }
@@ -1167,7 +1173,7 @@
        } else {
                uvm_fault_lower_generic_lookup(ufi, flt, pages);
        }
-       return uvm_fault_lower_generic1(ufi, flt, pages);
+       return uvm_fault_lower_generic1(ufi, flt, pages[flt->centeridx]);
 }
 
 static int
@@ -1275,12 +1281,11 @@
 static int
 uvm_fault_lower_generic1(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
-       struct vm_page **pages)
+       struct vm_page *uobjpage)
 {
 #ifdef DIAGNOSTIC
        struct vm_amap *amap = ufi->entry->aref.ar_amap;
        struct uvm_object *uobj = ufi->entry->object.uvm_obj;
-       struct vm_page *uobjpage = pages[flt->centeridx];
 #endif
 
        /* locked: maps(read), amap(if there), uobj(if !null), uobjpage(if !null) */
@@ -1307,17 +1312,44 @@
         * redirect case 2: if we are not shadowed, go to case 2.
         */
 
-       return uvm_fault_lower_generic2(ufi, flt, pages);
+       return uvm_fault_lower_generic2(ufi, flt, uobjpage);
 }
 
 static int
+uvm_fault_upper_loan(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_anon *anon, struct uvm_object **ruobj);
+static int
+uvm_fault_upper1(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon);
+static int
+uvm_fault_upper_promote(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon);
+static int
+uvm_fault_upper_direct(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon);
+static int
+uvm_fault_upper_enter(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon,
+       struct vm_page *pg, struct vm_anon *oanon);
+static int
+uvm_fault_upper_done(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon,
+       struct vm_page *pg, struct vm_anon *oanon);
+
+static int
 uvm_fault_upper(
        struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
-       struct vm_anon **anons, struct vm_page **pages)
+       struct vm_anon **anons)
 {
-       struct vm_amap *amap = ufi->entry->aref.ar_amap;
-       struct uvm_object *uobj = ufi->entry->object.uvm_obj;
-       struct vm_anon *anon, *oanon;
+       struct vm_amap * const amap = ufi->entry->aref.ar_amap;
+       struct vm_anon * const anon = anons[flt->centeridx];
+       struct uvm_object *uobj;
        int error;
 
        /* locked: maps(read), amap */
@@ -1327,7 +1359,6 @@
         * handle case 1: fault on an anon in our amap
         */
 
-       anon = anons[flt->centeridx];
        UVMHIST_LOG(maphist, "  case 1 fault: anon=0x%x", anon, 0,0,0);
        mutex_enter(&anon->an_lock);
 
@@ -1381,6 +1412,20 @@
         */
 
        if (anon->an_page->loan_count) {
+               error = uvm_fault_upper_loan(ufi, flt, anon, &uobj);
+               if (error != 0)
+                       return error;
+       }
+       return uvm_fault_upper1(ufi, flt, uobj, anon);
+}
+
+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;
 
                if (!flt->cow_now) {
 
@@ -1446,7 +1491,7 @@
 
                                if (uobj) {
                                        mutex_exit(&uobj->vmobjlock);
-                                       uobj = NULL;
+                                       *ruobj = NULL;
                                }
 
                                /* install new page in anon */
@@ -1463,7 +1508,16 @@
                                /* done! */
                        }     /* ref == 1 */
                }       /* write fault */
-       }         /* loan count */
+
+               return 0;
+}
+
+static int
+uvm_fault_upper1(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon)
+{
+       int error;
 
        /*
         * if we are case 1B then we will need to allocate a new blank
@@ -1478,12 +1532,25 @@
         * if we are out of anon VM we kill the process (XXX: could wait?).
         */
 
-       struct vm_page *pg;
        if (flt->cow_now && anon->an_ref > 1) {
+               error = uvm_fault_upper_promote(ufi, flt, uobj, anon);
+       } else {
+               error = uvm_fault_upper_direct(ufi, flt, uobj, anon);
+       }
+       return error;
+}
+
+static int
+uvm_fault_upper_promote(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon)
+{
+               struct vm_anon * const oanon = anon;
+               struct vm_page *pg;
+               int error;
 
                UVMHIST_LOG(maphist, "  case 1B: COW fault",0,0,0,0);
                uvmexp.flt_acow++;
-               oanon = anon;           /* oanon = old, locked anon */
 
                error = uvmfault_promote(ufi, oanon, PGO_DONTCARE,
                    &anon, &flt->anon_spare);
@@ -1512,15 +1579,32 @@
                 * oanon != anon, we'll have to unlock anon, too.
                 */
 
-       } else {
+               return uvm_fault_upper_enter(ufi, flt, uobj, anon, pg, oanon);
+}
+
+static int
+uvm_fault_upper_direct(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon)
+{
+               struct vm_anon * const oanon = anon;
+               struct vm_page *pg;
 
                uvmexp.flt_anon++;
-               oanon = anon;           /* old, locked anon is same as anon */
                pg = anon->an_page;
                if (anon->an_ref > 1)     /* disallow writes to ref > 1 anons */
                        flt->enter_prot = flt->enter_prot & ~VM_PROT_WRITE;
 
-       }
+               return uvm_fault_upper_enter(ufi, flt, uobj, anon, pg, oanon);
+}
+
+static int
+uvm_fault_upper_enter(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon, struct vm_page *pg,
+       struct vm_anon *oanon)
+{
+       struct vm_amap * const amap = ufi->entry->aref.ar_amap;
 
        /* locked: maps(read), amap, oanon, anon (if different from oanon) */
        KASSERT(mutex_owned(&amap->am_l));
@@ -1552,14 +1636,24 @@
                        UVMHIST_LOG(maphist,
                            "<- failed.  out of VM",0,0,0,0);
                        /* XXX instrumentation */
-                       error = ENOMEM;
-                       return error;
+                       return ENOMEM;
                }
                /* XXX instrumentation */
                uvm_wait("flt_pmfail1");
                return ERESTART;
        }
 
+       return uvm_fault_upper_done(ufi, flt, uobj, anon, pg, oanon);
+}
+
+static int
+uvm_fault_upper_done(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj, struct vm_anon *anon,
+       struct vm_page *pg, struct vm_anon *oanon)
+{
+       struct vm_amap * const amap = ufi->entry->aref.ar_amap;
+
        /*
         * ... update the page queues.
         */
@@ -1594,14 +1688,41 @@
 }
 
 static int
+uvm_fault_lower_generic_io(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page **ruobjpage);
+static int
+uvm_fault_lower_generic_uobjpage(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page *uobjpage, bool promote);
+static int
+uvm_fault_lower_generic_direct(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page *uobjpage);
+static int
+uvm_fault_lower_generic_promote(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct vm_page *uobjpage);
+static int
+uvm_fault_lower_generic_enter(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,
+       struct uvm_object *uobj,
+       struct vm_anon *anon, struct vm_page *pg, struct vm_page *uobjpage);
+static int
+uvm_fault_lower_generic_done(
+       struct uvm_faultinfo *ufi, struct uvm_faultctx *flt,



Home | Main Index | Thread Index | Old Index