Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm revert uvm_fault.c 1.104 for now. see PR/28372, PR/...
details: https://anonhg.NetBSD.org/src/rev/0c567dc2cc18
branches: trunk
changeset: 587602:0c567dc2cc18
user: yamt <yamt%NetBSD.org@localhost>
date: Mon Jan 30 11:50:17 2006 +0000
description:
revert uvm_fault.c 1.104 for now. see PR/28372, PR/32665.
diffstat:
sys/uvm/uvm_fault.c | 289 ++++++++++++++++++---------------------------------
1 files changed, 102 insertions(+), 187 deletions(-)
diffs (truncated from 434 to 300 lines):
diff -r 89b07f52f407 -r 0c567dc2cc18 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c Mon Jan 30 04:25:44 2006 +0000
+++ b/sys/uvm/uvm_fault.c Mon Jan 30 11:50:17 2006 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.104 2006/01/21 13:13:07 yamt Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.105 2006/01/30 11:50:17 yamt Exp $ */
/*
*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.104 2006/01/21 13:13:07 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.105 2006/01/30 11:50:17 yamt Exp $");
#include "opt_uvmhist.h"
@@ -536,143 +536,6 @@
}
/*
- * uvmfault_promote: promote data to a new anon. used for 1B and 2B.
- *
- * 1. allocate an anon and a page.
- * 2. fill its contents.
- * 3. put it into amap.
- *
- * => if we fail (result != 0) we unlock everything.
- * => on success, return a new locked anon via 'nanon'.
- * (*nanon)->an_page will be a resident, locked, dirty page.
- */
-
-static int
-uvmfault_promote(struct uvm_faultinfo *ufi,
- struct vm_anon *oanon,
- struct vm_page *uobjpage,
- struct vm_anon **nanon, /* OUT: allocated anon */
- struct vm_anon **spare)
-{
- struct vm_amap *amap = ufi->entry->aref.ar_amap;
- struct uvm_object *uobj;
- struct vm_anon *anon;
- struct vm_page *pg;
- struct vm_page *opg;
- int error;
- UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
-
- if (oanon) {
- /* anon COW */
- opg = oanon->an_page;
- KASSERT(opg != NULL);
- KASSERT(opg->uobject == NULL || opg->loan_count > 0);
- } else if (uobjpage != PGO_DONTCARE) {
- /* object-backed COW */
- opg = uobjpage;
- KASSERT(opg->uobject == ufi->entry->object.uvm_obj);
- } else {
- /* ZFOD */
- opg = NULL;
- }
- if (opg != NULL) {
- uobj = opg->uobject;
- } else {
- uobj = NULL;
- }
-
- KASSERT(amap != NULL);
- KASSERT(uobjpage != NULL);
- KASSERT(uobjpage == PGO_DONTCARE || (uobjpage->flags & PG_BUSY) != 0);
- LOCK_ASSERT(simple_lock_held(&amap->am_l));
- LOCK_ASSERT(oanon == NULL || simple_lock_held(&oanon->an_lock));
- LOCK_ASSERT(uobj == NULL || simple_lock_held(&uobj->vmobjlock));
- LOCK_ASSERT(*spare == NULL || !simple_lock_held(&(*spare)->an_lock));
-
- if (*spare != NULL) {
- anon = *spare;
- *spare = NULL;
- simple_lock(&anon->an_lock);
- } else if (ufi->map != kernel_map) {
- anon = uvm_analloc();
- } else {
- UVMHIST_LOG(maphist, "kernel_map, unlock and retry", 0,0,0,0);
-
- /*
- * we can't allocate anons with kernel_map locked.
- */
-
- uvm_page_unbusy(&uobjpage, 1);
- uvmfault_unlockall(ufi, amap, uobj, oanon);
-
- *spare = uvm_analloc();
- if (*spare == NULL) {
- goto nomem;
- }
- simple_unlock(&(*spare)->an_lock);
- error = ERESTART;
- goto done;
- }
- if (anon) {
-
- /*
- * The new anon is locked.
- *
- * if opg == NULL, we want a zero'd, dirty page,
- * so have uvm_pagealloc() do that for us.
- */
-
- pg = uvm_pagealloc(NULL, 0, anon,
- (opg == NULL) ? UVM_PGA_ZERO : 0);
- } else {
- pg = NULL;
- }
-
- /*
- * out of memory resources?
- */
-
- if (pg == NULL) {
- /* save anon for the next try. */
- if (anon != NULL) {
- simple_unlock(&anon->an_lock);
- *spare = anon;
- }
-
- /* unlock and fail ... */
- uvm_page_unbusy(&uobjpage, 1);
- uvmfault_unlockall(ufi, amap, uobj, oanon);
-nomem:
- if (!uvm_reclaimable()) {
- UVMHIST_LOG(maphist, "out of VM", 0,0,0,0);
- uvmexp.fltnoanon++;
- error = ENOMEM;
- goto done;
- }
-
- UVMHIST_LOG(maphist, "out of RAM, waiting for more", 0,0,0,0);
- uvmexp.fltnoram++;
- uvm_wait("flt_noram5");
- error = ERESTART;
- goto done;
- }
-
- /* copy page [pg now dirty] */
- if (opg) {
- uvm_pagecopy(opg, pg);
- }
-
- amap_add(&ufi->entry->aref, ufi->orig_rvaddr - ufi->entry->start, anon,
- oanon != NULL);
-
- *nanon = anon;
- error = 0;
-done:
- return error;
-}
-
-
-/*
* F A U L T - m a i n e n t r y p o i n t
*/
@@ -704,14 +567,13 @@
struct vm_amap *amap;
struct uvm_object *uobj;
struct vm_anon *anons_store[UVM_MAXRANGE], **anons, *anon, *oanon;
- struct vm_anon *anon_spare;
struct vm_page *pages[UVM_MAXRANGE], *pg, *uobjpage;
UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, ft=%d, at=%d)",
orig_map, vaddr, fault_type, access_type);
- anon = anon_spare = NULL;
+ anon = NULL;
pg = NULL;
uvmexp.faults++; /* XXX: locking? */
@@ -742,8 +604,7 @@
if (uvmfault_lookup(&ufi, FALSE) == FALSE) {
UVMHIST_LOG(maphist, "<- no mapping @ 0x%x", vaddr, 0,0,0);
- error = EFAULT;
- goto done;
+ return (EFAULT);
}
/* locked: maps(read) */
@@ -768,8 +629,7 @@
"<- protection failure (prot=0x%x, access=0x%x)",
ufi.entry->protection, access_type, 0, 0);
uvmfault_unlockmaps(&ufi, FALSE);
- error = EACCES;
- goto done;
+ return EACCES;
}
/*
@@ -832,8 +692,7 @@
if (amap == NULL && uobj == NULL) {
uvmfault_unlockmaps(&ufi, FALSE);
UVMHIST_LOG(maphist,"<- no backing store, no overlay",0,0,0,0);
- error = EFAULT;
- goto done;
+ return (EFAULT);
}
/*
@@ -1027,7 +886,7 @@
/*
* object fault routine responsible for pmap_update().
*/
- goto done;
+ return error;
}
/*
@@ -1205,7 +1064,7 @@
goto ReFault;
default:
- goto done;
+ return error;
}
/*
@@ -1321,24 +1180,41 @@
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, &anon_spare);
- switch (error) {
- case 0:
- break;
- case ERESTART:
- goto ReFault;
- default:
- goto done;
+ anon = uvm_analloc();
+ if (anon) {
+ /* new anon is locked! */
+ pg = uvm_pagealloc(NULL, 0, anon, 0);
}
- pg = anon->an_page;
+ /* check for out of RAM */
+ if (anon == NULL || pg == NULL) {
+ if (anon) {
+ anon->an_ref--;
+ simple_unlock(&anon->an_lock);
+ uvm_anfree(anon);
+ }
+ uvmfault_unlockall(&ufi, amap, uobj, oanon);
+ if (!uvm_reclaimable()) {
+ UVMHIST_LOG(maphist,
+ "<- failed. out of VM",0,0,0,0);
+ uvmexp.fltnoanon++;
+ return ENOMEM;
+ }
+
+ uvmexp.fltnoram++;
+ uvm_wait("flt_noram3"); /* out of RAM, wait for more */
+ goto ReFault;
+ }
+
+ /* got all resources, replace anon with nanon */
+ uvm_pagecopy(oanon->an_page, pg);
uvm_lock_pageq();
uvm_pageactivate(pg);
+ pg->flags &= ~(PG_BUSY|PG_FAKE);
uvm_unlock_pageq();
- pg->flags &= ~(PG_BUSY|PG_FAKE);
UVM_PAGE_OWN(pg, NULL);
+ amap_add(&ufi.entry->aref, ufi.orig_rvaddr - ufi.entry->start,
+ anon, TRUE);
/* deref: can not drop to zero here by defn! */
oanon->an_ref--;
@@ -1386,8 +1262,7 @@
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
/* XXX instrumentation */
- error = ENOMEM;
- goto done;
+ return ENOMEM;
}
/* XXX instrumentation */
uvm_wait("flt_pmfail1");
@@ -1424,8 +1299,7 @@
simple_unlock(&anon->an_lock);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
pmap_update(ufi.orig_map->pmap);
- error = 0;
- goto done;
+ return 0;
Case2:
/*
Home |
Main Index |
Thread Index |
Old Index