summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/vm/vm_object.c13
-rw-r--r--sys/vm/vm_page.c3
2 files changed, 12 insertions, 4 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 1d71d85..0d904c3 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -1196,6 +1196,7 @@ vm_object_split(vm_map_entry_t entry)
orig_object->backing_object_offset + offset;
new_object->backing_object = source;
}
+ VM_OBJECT_LOCK(new_object);
VM_OBJECT_LOCK(orig_object);
for (idx = 0; idx < size; idx++) {
retry:
@@ -1211,15 +1212,22 @@ vm_object_split(vm_map_entry_t entry)
* not be changed by this operation.
*/
vm_page_lock_queues();
- if (vm_page_sleep_if_busy(m, TRUE, "spltwt"))
+ if ((m->flags & PG_BUSY) || m->busy) {
+ vm_page_flag_set(m, PG_WANTED | PG_REFERENCED);
+ VM_OBJECT_UNLOCK(orig_object);
+ VM_OBJECT_UNLOCK(new_object);
+ msleep(m, &vm_page_queue_mtx, PDROP | PVM, "spltwt", 0);
+ VM_OBJECT_LOCK(new_object);
+ VM_OBJECT_LOCK(orig_object);
goto retry;
-
+ }
vm_page_busy(m);
vm_page_rename(m, new_object, idx);
/* page automatically made dirty by rename and cache handled */
vm_page_busy(m);
vm_page_unlock_queues();
}
+ VM_OBJECT_UNLOCK(new_object);
if (orig_object->type == OBJT_SWAP) {
vm_object_pip_add(orig_object, 1);
VM_OBJECT_UNLOCK(orig_object);
@@ -1828,6 +1836,7 @@ vm_object_set_writeable_dirty(vm_object_t object)
{
struct vnode *vp;
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
vm_object_set_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY);
if (object->type == OBJT_VNODE &&
(vp = (struct vnode *)object->handle) != NULL) {
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 56c1c23..4015593 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -522,8 +522,7 @@ vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)
{
vm_page_t root;
- if (!VM_OBJECT_LOCKED(object))
- GIANT_REQUIRED;
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
if (m->object != NULL)
panic("vm_page_insert: already inserted");
OpenPOWER on IntegriCloud