Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm Ax uvm_fault_internal() & break it into functions. ...



details:   https://anonhg.NetBSD.org/src/rev/d5ded1dd26af
branches:  trunk
changeset: 751317:d5ded1dd26af
user:      uebayasi <uebayasi%NetBSD.org@localhost>
date:      Sun Jan 31 17:13:38 2010 +0000

description:
Ax uvm_fault_internal() & break it into functions.  "Upper" fault and "lower"
fault routines are separated now.

diffstat:

 sys/uvm/uvm_fault.c |  330 ++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 242 insertions(+), 88 deletions(-)

diffs (truncated from 654 to 300 lines):

diff -r 1a75b7b69f38 -r d5ded1dd26af sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c       Sun Jan 31 16:04:34 2010 +0000
+++ b/sys/uvm/uvm_fault.c       Sun Jan 31 17:13:38 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_fault.c,v 1.137 2010/01/31 09:20:31 uebayasi Exp $ */
+/*     $NetBSD: uvm_fault.c,v 1.138 2010/01/31 17:13:38 uebayasi Exp $ */
 
 /*
  *
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.137 2010/01/31 09:20:31 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.138 2010/01/31 17:13:38 uebayasi Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -692,6 +692,31 @@
 #define UVM_FAULT_WIRE         (1 << 0)
 #define UVM_FAULT_MAXPROT      (1 << 1)
 
+typedef int
+uvm_fault_subfunc_t(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page *uobjpage);
+static uvm_fault_subfunc_t uvm_fault_lower;
+static uvm_fault_subfunc_t uvm_fault_lower_special;
+static uvm_fault_subfunc_t uvm_fault_lower_generic;
+static uvm_fault_subfunc_t uvm_fault_lower_generic1;
+static uvm_fault_subfunc_t uvm_fault_upper;
+static uvm_fault_subfunc_t uvm_fault_lower_generic2;
+static void
+uvm_fault_lower_generic_lookup(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page **ruobjpage);
+
 int
 uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr,
     vm_prot_t access_type, int fault_flag)
@@ -705,7 +730,7 @@
        struct uvm_object *uobj;
        struct vm_anon *anons_store[UVM_MAXRANGE], **anons;
        struct vm_anon *anon_spare;
-       struct vm_page *pages[UVM_MAXRANGE], *uobjpage;
+       struct vm_page *pages[UVM_MAXRANGE], *uobjpage = NULL;
        UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist);
 
        UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, at=%d, ff=%d)",
@@ -734,7 +759,38 @@
         */
 ReFault:
 
-/* uvm_fault_prepare */
+       goto uvm_fault_prepare;
+uvm_fault_prepare_done:
+
+       goto uvm_fault_upper_lookup;
+uvm_fault_upper_lookup_done:
+
+       if (shadowed == true)
+               error = uvm_fault_upper(
+                       &ufi, access_type, enter_prot,
+                       wired, narrow, shadowed, wire_fault, cow_now,
+                       npages, centeridx, startva,
+                       amap, uobj, anons_store, anons, &anon_spare,
+                       pages, uobjpage);
+       else
+               error = uvm_fault_lower(
+                       &ufi, access_type, enter_prot,
+                       wired, narrow, shadowed, wire_fault, cow_now,
+                       npages, centeridx, startva,
+                       amap, uobj, anons_store, anons, &anon_spare,
+                       pages, uobjpage);
+
+       if (error == -ERESTART)
+               goto ReFault;
+
+done:
+       if (anon_spare != NULL) {
+               anon_spare->an_ref--;
+               uvm_anfree(anon_spare);
+       }
+       return error;
+
+uvm_fault_prepare:
     {
        vm_prot_t check_prot;
        int nback, nforw;
@@ -930,13 +986,14 @@
                centeridx = 0;
        }
     }
+       goto uvm_fault_prepare_done;
 
        /*
         * => startva is fixed
         * => npages is fixed
         */
 
-/* uvm_fault_upper_lookup */
+uvm_fault_upper_lookup:
     {
        int lcv;
        vaddr_t currva;
@@ -1026,11 +1083,21 @@
         * XXX case.  --thorpej
         */
     }
+       goto uvm_fault_upper_lookup_done;
+}
 
-       if (shadowed == true)
-               goto Case1;
+static int
+uvm_fault_lower(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page *uobjpage)
+{
+       int error;
 
-/* uvm_fault_lower */
        /*
         * if the desired page is not shadowed by the amap and we have a
         * backing object, then we check to see if the backing object would
@@ -1040,26 +1107,61 @@
         */
 
        if (uobj && uobj->pgops->pgo_fault != NULL) {
-/* uvm_fault_lower_special */
+               error = uvm_fault_lower_special(
+                       ufi, access_type, enter_prot,
+                       wired, narrow, shadowed, wire_fault, cow_now,
+                       npages, centeridx, startva,
+                       amap, uobj, anons_store, anons, ranon_spare,
+                       pages, uobjpage);
+       } else {
+               error = uvm_fault_lower_generic(
+                       ufi, access_type, enter_prot,
+                       wired, narrow, shadowed, wire_fault, cow_now,
+                       npages, centeridx, startva,
+                       amap, uobj, anons_store, anons, ranon_spare,
+                       pages, uobjpage);
+       }
+       return error;
+}
+
+static int
+uvm_fault_lower_special(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page *uobjpage)
+{
+       int error;
+
                mutex_enter(&uobj->vmobjlock);
                /* locked: maps(read), amap (if there), uobj */
-               error = uobj->pgops->pgo_fault(&ufi, startva, pages, npages,
+               error = uobj->pgops->pgo_fault(ufi, startva, pages, npages,
                    centeridx, access_type, PGO_LOCKED|PGO_SYNCIO);
 
                /* locked: nothing, pgo_fault has unlocked everything */
 
                if (error == ERESTART)
-                       goto ReFault;           /* try again! */
+                       error = -ERESTART;              /* try again! */
                /*
                 * object fault routine responsible for pmap_update().
                 */
-               goto done;
-       }
+
+               return error;
+}
 
-/* uvm_fault_lower_generic_lookup */
-    {
-       int lcv, gotpages;
-       vaddr_t currva;
+static int
+uvm_fault_lower_generic(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page *uobjpage)
+{
 
        /*
         * now, if the desired page is not shadowed by the amap and we have
@@ -1072,8 +1174,35 @@
        if (uobj == NULL) {
                /* zero fill; don't care neighbor pages */
                uobjpage = NULL;
-               goto lower_fault_lookup_done;
+       } else {
+               uvm_fault_lower_generic_lookup(
+                       ufi, access_type, enter_prot,
+                       wired, narrow, shadowed, wire_fault, cow_now,
+                       npages, centeridx, startva,
+                       amap, uobj, anons_store, anons, ranon_spare,
+                       pages, &uobjpage);
        }
+       return uvm_fault_lower_generic1(
+               ufi, access_type, enter_prot,
+               wired, narrow, shadowed, wire_fault, cow_now,
+               npages, centeridx, startva,
+               amap, uobj, anons_store, anons, ranon_spare,
+               pages, uobjpage);
+}
+
+static void
+uvm_fault_lower_generic_lookup(
+       struct uvm_faultinfo *ufi, vm_prot_t access_type, vm_prot_t enter_prot,
+       bool wired, bool narrow, bool shadowed, bool wire_fault, bool cow_now,
+       int npages, int centeridx, vaddr_t startva,
+       struct vm_amap *amap, struct uvm_object *uobj,
+       struct vm_anon **anons_store, struct vm_anon **anons,
+       struct vm_anon **ranon_spare,
+       struct vm_page **pages, struct vm_page **ruobjpage)
+{
+       int lcv, gotpages;
+       vaddr_t currva;
+       struct vm_page *uobjpage;
 
        mutex_enter(&uobj->vmobjlock);
        /* locked (!shadowed): maps(read), amap (if there), uobj */
@@ -1083,10 +1212,10 @@
 
        uvmexp.fltlget++;
        gotpages = npages;
-       (void) uobj->pgops->pgo_get(uobj, ufi.entry->offset + startva - ufi.entry->start,
+       (void) uobj->pgops->pgo_get(uobj, ufi->entry->offset + startva - ufi->entry->start,
                        pages, &gotpages, centeridx,
-                       access_type & MASK(ufi.entry),
-                       ufi.entry->advice, PGO_LOCKED);
+                       access_type & MASK(ufi->entry),
+                       ufi->entry->advice, PGO_LOCKED);
 
        /*
         * check for pages to map, if we got any
@@ -1095,7 +1224,7 @@
        uobjpage = NULL;
 
        if (gotpages == 0)
-               goto lower_fault_lookup_done;
+               goto done;
 
        currva = startva;
        for (lcv = 0; lcv < npages;
@@ -1137,7 +1266,7 @@
                mutex_exit(&uvm_pageqlock);
                UVMHIST_LOG(maphist,
                  "  MAPPING: n obj: pm=0x%x, va=0x%x, pg=0x%x",
-                 ufi.orig_map->pmap, currva, curpg, 0);
+                 ufi->orig_map->pmap, currva, curpg, 0);
                uvmexp.fltnomap++;
 
                /*
@@ -1154,11 +1283,11 @@
                    || (curpg->loan_count > 0)
                    || UVM_OBJ_NEEDS_WRITEFAULT(curpg->uobject);
 
-               (void) pmap_enter(ufi.orig_map->pmap, currva,
+               (void) pmap_enter(ufi->orig_map->pmap, currva,
                    VM_PAGE_TO_PHYS(curpg),
                    readonly ?
                    enter_prot & ~VM_PROT_WRITE :
-                   enter_prot & MASK(ufi.entry),
+                   enter_prot & MASK(ufi->entry),
                    PMAP_CANFAIL |
                     (wired ? PMAP_WIRED : 0));
 
@@ -1173,11 +1302,21 @@
                curpg->flags &= ~(PG_BUSY);
                UVM_PAGE_OWN(curpg, NULL);
        }
-       pmap_update(ufi.orig_map->pmap);
+       pmap_update(ufi->orig_map->pmap);



Home | Main Index | Thread Index | Old Index