diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-07-03 11:38:47 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2014-07-03 11:38:47 +0000 |
commit | b368263f0c2a9d7884562baf19d6dfe8a8f3aab7 (patch) | |
tree | c19d5bb80dbca71b10ded7264d34071e1f9da215 | |
parent | f96313b2e43d4c6392e2324b175e92e7eb3686f1 (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.c | 7 | ||||
-rw-r--r-- | sys/uvm/uvm_fault.c | 18 |
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); |