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