Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/uebayasi-xip]: src/sys/uvm Teach device page handling to the "lower" fau...
details: https://anonhg.NetBSD.org/src/rev/2134930b672d
branches: uebayasi-xip
changeset: 751577:2134930b672d
user: uebayasi <uebayasi%NetBSD.org@localhost>
date: Fri Feb 12 16:09:56 2010 +0000
description:
Teach device page handling to the "lower" fault handler. Skip all the paging
activities, no loaning, no wired count. Only compile tested so far.
diffstat:
sys/uvm/uvm_fault.c | 67 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 51 insertions(+), 16 deletions(-)
diffs (216 lines):
diff -r 356799bfc118 -r 2134930b672d sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c Fri Feb 12 16:06:50 2010 +0000
+++ b/sys/uvm/uvm_fault.c Fri Feb 12 16:09:56 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.166.2.2 2010/02/12 16:06:50 uebayasi Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.166.2.3 2010/02/12 16:09:56 uebayasi Exp $ */
/*
*
@@ -39,9 +39,10 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.166.2.2 2010/02/12 16:06:50 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.166.2.3 2010/02/12 16:09:56 uebayasi Exp $");
#include "opt_uvmhist.h"
+#include "opt_xip.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -573,7 +574,8 @@
KASSERT(amap != NULL);
KASSERT(uobjpage != NULL);
- KASSERT(uobjpage == PGO_DONTCARE || (uobjpage->flags & PG_BUSY) != 0);
+ KASSERT(uobjpage == PGO_DONTCARE || uvm_pageisdevice_p(uobjpage) ||
+ (uobjpage->flags & PG_BUSY) != 0);
KASSERT(mutex_owned(&amap->am_l));
KASSERT(oanon == NULL || mutex_owned(&oanon->an_lock));
KASSERT(uobj == NULL || mutex_owned(&uobj->vmobjlock));
@@ -1235,7 +1237,8 @@
/* locked: maps(read), amap(if there), uobj(if !null), uobjpage(if !null) */
KASSERT(amap == NULL || mutex_owned(&amap->am_l));
KASSERT(uobj == NULL || mutex_owned(&uobj->vmobjlock));
- KASSERT(uobjpage == NULL || (uobjpage->flags & PG_BUSY) != 0);
+ KASSERT(uobjpage == NULL || uvm_pageisdevice_p(uobjpage) ||
+ (uobjpage->flags & PG_BUSY) != 0);
/*
* note that at this point we are done with any front or back pages.
@@ -1299,7 +1302,7 @@
if (curpg == NULL || curpg == PGO_DONTCARE) {
continue;
}
- KASSERT(curpg->uobject == uobj);
+ KASSERT(uvm_pageisdevice_p(curpg) || curpg->uobject == uobj);
/*
* if center page is resident and not PG_BUSY|PG_RELEASED
@@ -1312,7 +1315,8 @@
"(0x%x) with locked get",
curpg, 0,0,0);
} else {
- bool readonly = (curpg->flags & PG_RDONLY)
+ bool readonly = uvm_pageisdevice_p(curpg)
+ || (curpg->flags & PG_RDONLY)
|| (curpg->loan_count > 0)
|| UVM_OBJ_NEEDS_WRITEFAULT(curpg->uobject);
@@ -1331,6 +1335,9 @@
{
UVMHIST_FUNC("uvm_fault_lower_neighor"); UVMHIST_CALLED(maphist);
+ if (uvm_pageisdevice_p(pg))
+ goto uvm_fault_lower_neighbor_enter;
+
/*
* calling pgo_get with PGO_LOCKED returns us pages which
* are neither busy nor released, so we don't need to check
@@ -1355,12 +1362,16 @@
KASSERT(!UVM_OBJ_IS_CLEAN(pg->uobject) ||
(pg->flags & PG_CLEAN) != 0);
+uvm_fault_lower_neighbor_enter:
(void) pmap_enter(ufi->orig_map->pmap, currva,
VM_PAGE_TO_PHYS(pg),
readonly ? (flt->enter_prot & ~VM_PROT_WRITE) :
flt->enter_prot & MASK(ufi->entry),
PMAP_CANFAIL | (flt->wire_mapping ? PMAP_WIRED : 0));
+ if (uvm_pageisdevice_p(pg))
+ goto uvm_fault_lower_neighbor_done;
+
/*
* NOTE: page can't be PG_WANTED or PG_RELEASED because we've
* held the lock the whole time we've had the handle.
@@ -1370,6 +1381,9 @@
pg->flags &= ~(PG_BUSY);
UVM_PAGE_OWN(pg, NULL);
+
+uvm_fault_lower_neighbor_done:
+ ;
}
static int
@@ -1687,7 +1701,8 @@
*/
KASSERT(amap == NULL || mutex_owned(&amap->am_l));
KASSERT(uobj == NULL || mutex_owned(&uobj->vmobjlock));
- KASSERT(uobjpage == NULL || (uobjpage->flags & PG_BUSY) != 0);
+ KASSERT(uobjpage == NULL || uvm_pageisdevice_p(uobjpage) ||
+ (uobjpage->flags & PG_BUSY) != 0);
/*
* note that uobjpage can not be PGO_DONTCARE at this point. we now
@@ -1730,7 +1745,8 @@
*/
KASSERT(amap == NULL || mutex_owned(&amap->am_l));
KASSERT(uobj == NULL || mutex_owned(&uobj->vmobjlock));
- KASSERT(uobj == NULL || (uobjpage->flags & PG_BUSY) != 0);
+ KASSERT(uobj == NULL || uvm_pageisdevice_p(uobjpage) ||
+ (uobjpage->flags & PG_BUSY) != 0);
/*
* notes:
@@ -1740,8 +1756,10 @@
* - at this point uobjpage could be PG_WANTED (handle later)
*/
- KASSERT(uobj == NULL || uobj == uobjpage->uobject);
- KASSERT(uobj == NULL || !UVM_OBJ_IS_CLEAN(uobjpage->uobject) ||
+ KASSERT(uvm_pageisdevice_p(uobjpage) || uobj == NULL ||
+ uobj == uobjpage->uobject);
+ KASSERT(uvm_pageisdevice_p(uobjpage) || uobj == NULL ||
+ !UVM_OBJ_IS_CLEAN(uobjpage->uobject) ||
(uobjpage->flags & PG_CLEAN) != 0);
if (promote == false) {
@@ -1897,12 +1915,15 @@
*
* set "pg" to the page we want to map in (uobjpage, usually)
*/
+ pg = uobjpage; /* map in the actual object */
+
+ if (uvm_pageisdevice_p(uobjpage))
+ goto uvm_fault_lower_direct_done;
uvmexp.flt_obj++;
if (UVM_ET_ISCOPYONWRITE(ufi->entry) ||
UVM_OBJ_NEEDS_WRITEFAULT(uobjpage->uobject))
flt->enter_prot &= ~VM_PROT_WRITE;
- pg = uobjpage; /* map in the actual object */
KASSERT(uobjpage != PGO_DONTCARE);
@@ -1916,6 +1937,7 @@
}
KASSERT(pg == uobjpage);
+uvm_fault_lower_direct_done:
return uvm_fault_lower_enter(ufi, flt, uobj, NULL, pg, uobjpage);
}
@@ -2065,9 +2087,10 @@
*/
KASSERT(amap == NULL || mutex_owned(&amap->am_l));
KASSERT(uobj == NULL || mutex_owned(&uobj->vmobjlock));
- KASSERT(uobj == NULL || (uobjpage->flags & PG_BUSY) != 0);
+ KASSERT(uobj == NULL || uvm_pageisdevice_p(uobjpage) ||
+ (uobjpage->flags & PG_BUSY) != 0);
KASSERT(anon == NULL || mutex_owned(&anon->an_lock));
- KASSERT((pg->flags & PG_BUSY) != 0);
+ KASSERT(uvm_pageisdevice_p(pg) || (pg->flags & PG_BUSY) != 0);
/*
* all resources are present. we can now map it in and free our
@@ -2078,11 +2101,16 @@
" MAPPING: case2: pm=0x%x, va=0x%x, pg=0x%x, promote=XXX",
ufi->orig_map->pmap, ufi->orig_rvaddr, pg, 0);
KASSERT((flt->access_type & VM_PROT_WRITE) == 0 ||
- (pg->flags & PG_RDONLY) == 0);
- if (pmap_enter(ufi->orig_map->pmap, ufi->orig_rvaddr, VM_PAGE_TO_PHYS(pg),
- pg->flags & PG_RDONLY ? flt->enter_prot & ~VM_PROT_WRITE : flt->enter_prot,
+ uvm_pageisdevice_p(pg) || (pg->flags & PG_RDONLY) == 0);
+ if (pmap_enter(ufi->orig_map->pmap, ufi->orig_rvaddr,
+ VM_PAGE_TO_PHYS(pg),
+ (uvm_pageisdevice_p(pg) || pg->flags & PG_RDONLY) ?
+ (flt->enter_prot & ~VM_PROT_WRITE) : flt->enter_prot,
flt->access_type | PMAP_CANFAIL | (flt->wire_mapping ? PMAP_WIRED : 0)) != 0) {
+ if (uvm_pageisdevice_p(pg))
+ goto uvm_fault_lower_enter_error_done;
+
/*
* No need to undo what we did; we can simply think of
* this as the pmap throwing away the mapping information.
@@ -2102,6 +2130,8 @@
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
+
+uvm_fault_lower_enter_error_done:
uvmfault_unlockall(ufi, amap, uobj, anon);
if (!uvm_reclaimable()) {
UVMHIST_LOG(maphist,
@@ -2126,6 +2156,9 @@
struct vm_amap * const amap = ufi->entry->aref.ar_amap;
UVMHIST_FUNC("uvm_fault_lower_done"); UVMHIST_CALLED(maphist);
+ if (uvm_pageisdevice_p(pg))
+ goto uvm_fault_lower_done_done;
+
mutex_enter(&uvm_pageqlock);
if (flt->wire_paging) {
uvm_pagewire(pg);
@@ -2157,6 +2190,8 @@
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
+
+uvm_fault_lower_done_done:
uvmfault_unlockall(ufi, amap, uobj, anon);
pmap_update(ufi->orig_map->pmap);
UVMHIST_LOG(maphist, "<- done (SUCCESS!)",0,0,0,0);
Home |
Main Index |
Thread Index |
Old Index