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