From bbf4b0c0bf425448cec9b0e1e4f1898f7f07fd38 Mon Sep 17 00:00:00 2001 From: kmacy Date: Fri, 30 Apr 2010 21:20:14 +0000 Subject: [PATCH] - acquire the page lock in vm_contig_launder_page before checking page fields - release page queue lock before calling vm_pageout_flush --- sys/vm/vm_contig.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 7220055cd259..2c8b8b11c251 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -96,30 +96,33 @@ vm_contig_launder_page(vm_page_t m, vm_page_t *next) vm_page_t m_tmp; struct vnode *vp; struct mount *mp; - int vfslocked; + int vfslocked, dirty; - mtx_assert(&vm_page_queue_mtx, MA_OWNED); + vm_page_lock(m); + vm_page_lock_queues(); object = m->object; if (!VM_OBJECT_TRYLOCK(object) && !vm_pageout_fallback_object_lock(m, next)) { VM_OBJECT_UNLOCK(object); + vm_page_unlock_queues(); + vm_page_unlock(m); return (EAGAIN); } if (vm_page_sleep_if_busy(m, TRUE, "vpctw0")) { VM_OBJECT_UNLOCK(object); - vm_page_lock_queues(); return (EBUSY); } vm_page_test_dirty(m); if (m->dirty == 0 && m->hold_count == 0) pmap_remove_all(m); - if (m->dirty) { + if ((dirty = m->dirty) != 0) { + vm_page_unlock_queues(); + vm_page_unlock(m); if ((object->flags & OBJ_DEAD) != 0) { VM_OBJECT_UNLOCK(object); return (EAGAIN); } if (object->type == OBJT_VNODE) { - vm_page_unlock_queues(); vp = object->handle; vm_object_reference_locked(object); VM_OBJECT_UNLOCK(object); @@ -133,7 +136,6 @@ vm_contig_launder_page(vm_page_t m, vm_page_t *next) VFS_UNLOCK_GIANT(vfslocked); vm_object_deallocate(object); vn_finished_write(mp); - vm_page_lock_queues(); return (0); } else if (object->type == OBJT_SWAP || object->type == OBJT_DEFAULT) { @@ -144,6 +146,11 @@ vm_contig_launder_page(vm_page_t m, vm_page_t *next) } } else if (m->hold_count == 0) vm_page_cache(m); + + if (dirty == 0) { + vm_page_unlock_queues(); + vm_page_unlock(m); + } VM_OBJECT_UNLOCK(object); return (0); } @@ -162,7 +169,9 @@ vm_contig_launder(int queue) KASSERT(VM_PAGE_INQUEUE2(m, queue), ("vm_contig_launder: page %p's queue is not %d", m, queue)); + vm_page_unlock_queues(); error = vm_contig_launder_page(m, &next); + vm_page_lock_queues(); if (error == 0) return (TRUE); if (error == EBUSY)