Module Name:    src
Committed By:   uebayasi
Date:           Fri Feb 12 16:09:56 UTC 2010

Modified Files:
        src/sys/uvm [uebayasi-xip]: uvm_fault.c

Log Message:
Teach device page handling to the "lower" fault handler.  Skip all the paging
activities, no loaning, no wired count.  Only compile tested so far.


To generate a diff of this commit:
cvs rdiff -u -r1.166.2.1 -r1.166.2.2 src/sys/uvm/uvm_fault.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/uvm/uvm_fault.c
diff -u src/sys/uvm/uvm_fault.c:1.166.2.1 src/sys/uvm/uvm_fault.c:1.166.2.2
--- src/sys/uvm/uvm_fault.c:1.166.2.1	Fri Feb 12 16:06:50 2010
+++ src/sys/uvm/uvm_fault.c	Fri Feb 12 16:09:56 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_fault.c,v 1.166.2.1 2010/02/12 16:06:50 uebayasi Exp $	*/
+/*	$NetBSD: uvm_fault.c,v 1.166.2.2 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.1 2010/02/12 16:06:50 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.166.2.2 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);

Reply via email to