summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_fault.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-06-16 00:11:30 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-06-16 00:11:30 +0000
commitb20700966027364e7e2e3cf5ca4613cbb4e2a25b (patch)
treedac29c9a1582e023159a8aabe2282775b21cbdc2 /sys/uvm/uvm_fault.c
parentab37797a62467132f94babf9bc9d57cef8402599 (diff)
Backout all changes to uvm after pmemrange (which will be backed out
separately). a change at or just before the hackathon has either exposed or added a very very nasty memory corruption bug that is giving us hell right now. So in the interest of kernel stability these diffs are being backed out until such a time as that corruption bug has been found and squashed, then the ones that are proven good may slowly return. a quick hitlist of the main commits this backs out: mine: uvm_objwire the lock change in uvm_swap.c using trees for uvm objects instead of the hash removing the pgo_releasepg callback. art@'s: putting pmap_page_protect(VM_PROT_NONE) in uvm_pagedeactivate() since all callers called that just prior anyway. ok beck@, ariane@. prompted by deraadt@.
Diffstat (limited to 'sys/uvm/uvm_fault.c')
-rw-r--r--sys/uvm/uvm_fault.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index e0e8946c49c..0c7f05b6459 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_fault.c,v 1.55 2009/06/06 17:46:44 art Exp $ */
+/* $OpenBSD: uvm_fault.c,v 1.56 2009/06/16 00:11:29 oga Exp $ */
/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/*
@@ -203,6 +203,11 @@ uvmfault_anonflush(struct vm_anon **anons, int n)
if (pg && (pg->pg_flags & PG_BUSY) == 0 && pg->loan_count == 0) {
uvm_lock_pageq();
if (pg->wire_count == 0) {
+#ifdef UBC
+ pmap_clear_reference(pg);
+#else
+ pmap_page_protect(pg, VM_PROT_NONE);
+#endif
uvm_pagedeactivate(pg);
}
uvm_unlock_pageq();
@@ -916,10 +921,10 @@ ReFault:
/*
* if center page is resident and not
- * PG_BUSY, then pgo_get made it PG_BUSY
- * for us and gave us a handle to it.
- * remember this page as "uobjpage."
- * (for later use).
+ * PG_BUSY|PG_RELEASED then pgo_get
+ * made it PG_BUSY for us and gave
+ * us a handle to it. remember this
+ * page as "uobjpage." (for later use).
*/
if (lcv == centeridx) {
@@ -961,8 +966,8 @@ ReFault:
(wired ? PMAP_WIRED : 0));
/*
- * NOTE: page can't be PG_WANTED because
- * we've held the lock the whole time
+ * NOTE: page can't be PG_WANTED or PG_RELEASED
+ * because we've held the lock the whole time
* we've had the handle.
*/
@@ -1366,12 +1371,15 @@ Case2:
/* locked(!locked): uobj, uobjpage */
/*
- * Re-verify that amap slot is still free. if there is
- * a problem, we unlock and clean up.
+ * verify that the page has not be released and re-verify
+ * that amap slot is still free. if there is a problem,
+ * we unlock and clean up.
*/
- if (locked && amap && amap_lookup(&ufi.entry->aref,
- ufi.orig_rvaddr - ufi.entry->start)) {
+ if ((uobjpage->pg_flags & PG_RELEASED) != 0 ||
+ (locked && amap &&
+ amap_lookup(&ufi.entry->aref,
+ ufi.orig_rvaddr - ufi.entry->start))) {
if (locked)
uvmfault_unlockall(&ufi, amap, NULL, NULL);
locked = FALSE;
@@ -1390,6 +1398,17 @@ Case2:
/* still holding object lock */
wakeup(uobjpage);
+ if (uobjpage->pg_flags & PG_RELEASED) {
+ uvmexp.fltpgrele++;
+ KASSERT(uobj->pgops->pgo_releasepg != NULL);
+
+ /* frees page */
+ if (uobj->pgops->pgo_releasepg(uobjpage,NULL))
+ /* unlock if still alive */
+ simple_unlock(&uobj->vmobjlock);
+ goto ReFault;
+ }
+
uvm_lock_pageq();
/* make sure it is in queues */
uvm_pageactivate(uobjpage);
@@ -1404,8 +1423,9 @@ Case2:
}
/*
- * we have the data in uobjpage which is PG_BUSY and we are
- * holding object lock.
+ * we have the data in uobjpage which is PG_BUSY and
+ * !PG_RELEASED. we are holding object lock (so the page
+ * can't be released on us).
*/
/* locked: maps(read), amap(if !null), uobj, uobjpage */
@@ -1419,6 +1439,8 @@ Case2:
/*
* notes:
* - at this point uobjpage can not be NULL
+ * - at this point uobjpage can not be PG_RELEASED (since we checked
+ * for it above)
* - at this point uobjpage could be PG_WANTED (handle later)
*/
@@ -1605,7 +1627,9 @@ Case2:
}
/*
- * dispose of uobjpage. drop handle to uobj as well.
+ * dispose of uobjpage. it can't be PG_RELEASED
+ * since we still hold the object lock.
+ * drop handle to uobj as well.
*/
if (uobjpage->pg_flags & PG_WANTED)
@@ -1668,6 +1692,11 @@ Case2:
if (pg->pg_flags & PG_WANTED)
wakeup(pg); /* lock still held */
+ /*
+ * note that pg can't be PG_RELEASED since we did not drop
+ * the object lock since the last time we checked.
+ */
+
atomic_clearbits_int(&pg->pg_flags, PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
uvmfault_unlockall(&ufi, amap, uobj, NULL);
@@ -1707,6 +1736,11 @@ Case2:
if (pg->pg_flags & PG_WANTED)
wakeup(pg); /* lock still held */
+ /*
+ * note that pg can't be PG_RELEASED since we did not drop the object
+ * lock since the last time we checked.
+ */
+
atomic_clearbits_int(&pg->pg_flags, PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL);
uvmfault_unlockall(&ufi, amap, uobj, NULL);