Author: kmacy Date: Fri Apr 30 21:20:14 2010 New Revision: 207450 URL: http://svn.freebsd.org/changeset/base/207450
Log: - acquire the page lock in vm_contig_launder_page before checking page fields - release page queue lock before calling vm_pageout_flush Modified: head/sys/vm/vm_contig.c Modified: head/sys/vm/vm_contig.c ============================================================================== --- head/sys/vm/vm_contig.c Fri Apr 30 19:52:35 2010 (r207449) +++ head/sys/vm/vm_contig.c Fri Apr 30 21:20:14 2010 (r207450) @@ -96,30 +96,33 @@ vm_contig_launder_page(vm_page_t m, vm_p 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_p 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_p } } 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) _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"