diff options
author | jeff <jeff@FreeBSD.org> | 2015-03-28 02:36:49 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2015-03-28 02:36:49 +0000 |
commit | 2ef15783194ba96d4474939d1e64be02132da111 (patch) | |
tree | f04fcd2282d83d292d1ab278163fba089532d389 | |
parent | 09331b0ed03c8f83c47514a8679758764ecdc970 (diff) | |
download | FreeBSD-src-2ef15783194ba96d4474939d1e64be02132da111.zip FreeBSD-src-2ef15783194ba96d4474939d1e64be02132da111.tar.gz |
- Eliminate pagequeue locking in the dirty code in vm_pageout_scan().
- Use a more precise series of tests to see if the page changed while we
were locking the vnode.
Reviewed by: alc
Sponsored by: EMC / Isilon
-rw-r--r-- | sys/vm/vm_pageout.c | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index ecc3dab..2fb7c55 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1157,6 +1157,7 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) int swap_pageouts_ok; struct vnode *vp = NULL; struct mount *mp = NULL; + vm_pindex_t pindex; if ((object->type != OBJT_SWAP) && (object->type != OBJT_DEFAULT)) { swap_pageouts_ok = 1; @@ -1217,6 +1218,7 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) KASSERT(mp != NULL, ("vp %p with NULL v_mount", vp)); vm_object_reference_locked(object); + pindex = m->pindex; VM_OBJECT_WUNLOCK(object); lockmode = MNT_SHARED_WRITES(vp->v_mount) ? LK_SHARED : LK_EXCLUSIVE; @@ -1231,17 +1233,18 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) } VM_OBJECT_WLOCK(object); vm_page_lock(m); - vm_pagequeue_lock(pq); - queues_locked = TRUE; /* - * The page might have been moved to another - * queue during potential blocking in vget() - * above. The page might have been freed and - * reused for another vnode. + * While the object and page were unlocked, + * the page may have been + * (1) moved to a different queue, + * (2) reallocated to a different object, + * (3) reallocated to a different offset, or + * (4) cleaned. */ if (m->queue != PQ_INACTIVE || m->object != object || - TAILQ_NEXT(m, plinks.q) != &vmd->vmd_marker) { + m->pindex != pindex || + m->dirty == 0) { vm_page_unlock(m); if (object->flags & OBJ_MIGHTBEDIRTY) vnodes_skipped++; @@ -1271,8 +1274,6 @@ vm_pageout_scan(struct vm_domain *vmd, int pass) vnodes_skipped++; goto unlock_and_continue; } - vm_pagequeue_unlock(pq); - queues_locked = FALSE; } /* @@ -1293,10 +1294,6 @@ unlock_and_continue: vm_page_lock_assert(m, MA_NOTOWNED); VM_OBJECT_WUNLOCK(object); if (mp != NULL) { - if (queues_locked) { - vm_pagequeue_unlock(pq); - queues_locked = FALSE; - } if (vp != NULL) vput(vp); vm_object_deallocate(object); |