summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2014-07-03 11:38:47 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2014-07-03 11:38:47 +0000
commitb368263f0c2a9d7884562baf19d6dfe8a8f3aab7 (patch)
treec19d5bb80dbca71b10ded7264d34071e1f9da215
parentf96313b2e43d4c6392e2324b175e92e7eb3686f1 (diff)
It is important that we don't release the kernel lock between issuing a
wakeup and clearing the PG_BUSY and PG_WANTED flags, so try to keep those bits as close together and defenitely avoid calling random code in between. ok guenther@, tedu@
-rw-r--r--sys/uvm/uvm_aobj.c7
-rw-r--r--sys/uvm/uvm_fault.c18
2 files changed, 11 insertions, 14 deletions
diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c
index 153ca4d4716..8ad1c821394 100644
--- a/sys/uvm/uvm_aobj.c
+++ b/sys/uvm/uvm_aobj.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_aobj.c,v 1.64 2014/05/08 20:08:50 kettenis Exp $ */
+/* $OpenBSD: uvm_aobj.c,v 1.65 2014/07/03 11:38:46 kettenis Exp $ */
/* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -1207,9 +1207,6 @@ uao_get(struct uvm_object *uobj, voff_t offset, struct vm_page **pps,
/* I/O done. check for errors. */
if (rv != VM_PAGER_OK) {
- if (ptmp->pg_flags & PG_WANTED)
- wakeup(ptmp);
-
/*
* remove the swap slot from the aobj
* and mark the aobj as having no real slot.
@@ -1220,6 +1217,8 @@ uao_get(struct uvm_object *uobj, voff_t offset, struct vm_page **pps,
SWSLOT_BAD);
uvm_swap_markbad(swslot, 1);
+ if (ptmp->pg_flags & PG_WANTED)
+ wakeup(ptmp);
atomic_clearbits_int(&ptmp->pg_flags,
PG_WANTED|PG_BUSY);
UVM_PAGE_OWN(ptmp, NULL);
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index d739d4fc772..4a795fece07 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_fault.c,v 1.73 2014/05/08 20:08:50 kettenis Exp $ */
+/* $OpenBSD: uvm_fault.c,v 1.74 2014/07/03 11:38:46 kettenis Exp $ */
/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/*
@@ -1144,20 +1144,18 @@ Case2:
/* didn't get the lock? release the page and retry. */
if (locked == FALSE) {
- if (uobjpage->pg_flags & PG_WANTED)
- /* still holding object lock */
- wakeup(uobjpage);
-
uvm_lock_pageq();
/* make sure it is in queues */
uvm_pageactivate(uobjpage);
-
uvm_unlock_pageq();
+
+ if (uobjpage->pg_flags & PG_WANTED)
+ /* still holding object lock */
+ wakeup(uobjpage);
atomic_clearbits_int(&uobjpage->pg_flags,
PG_BUSY|PG_WANTED);
UVM_PAGE_OWN(uobjpage, NULL);
goto ReFault;
-
}
/*
@@ -1293,12 +1291,12 @@ Case2:
if (anon == NULL || pg == NULL) {
/* arg! must unbusy our page and fail or sleep. */
if (uobjpage != PGO_DONTCARE) {
- if (uobjpage->pg_flags & PG_WANTED)
- wakeup(uobjpage);
-
uvm_lock_pageq();
uvm_pageactivate(uobjpage);
uvm_unlock_pageq();
+
+ if (uobjpage->pg_flags & PG_WANTED)
+ wakeup(uobjpage);
atomic_clearbits_int(&uobjpage->pg_flags,
PG_BUSY|PG_WANTED);
UVM_PAGE_OWN(uobjpage, NULL);