svn commit: r271634 - head/sys/vm

Alan Cox alc at FreeBSD.org
Mon Sep 15 17:14:10 UTC 2014


Author: alc
Date: Mon Sep 15 17:14:09 2014
New Revision: 271634
URL: http://svnweb.freebsd.org/changeset/base/271634

Log:
  Three improvements to vnode_pager_generic_getpages():
  
  Eliminate an exclusive object lock acquisition and release on the expected
  execution path.
  
  Do page zeroing before the object lock is acquired rather than during the
  time that the object lock is held.
  
  Use vm_pager_free_nonreq() to eliminate duplicated code.
  
  Reviewed by:	kib
  MFC after:	6 weeks
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/vm/vnode_pager.c

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Mon Sep 15 16:47:04 2014	(r271633)
+++ head/sys/vm/vnode_pager.c	Mon Sep 15 17:14:09 2014	(r271634)
@@ -772,24 +772,24 @@ vnode_pager_generic_getpages(struct vnod
 	}
 
 	/*
+	 * Since the caller has busied the requested page, that page's valid
+	 * field will not be changed by other threads.
+	 */
+	vm_page_assert_xbusied(m[reqpage]);
+
+	/*
 	 * If we have a completely valid page available to us, we can
 	 * clean up and return.  Otherwise we have to re-read the
 	 * media.
 	 */
-	VM_OBJECT_WLOCK(object);
 	if (m[reqpage]->valid == VM_PAGE_BITS_ALL) {
-		for (i = 0; i < count; i++)
-			if (i != reqpage) {
-				vm_page_lock(m[i]);
-				vm_page_free(m[i]);
-				vm_page_unlock(m[i]);
-			}
-		VM_OBJECT_WUNLOCK(object);
-		return VM_PAGER_OK;
+		vm_pager_free_nonreq(object, m, reqpage, count);
+		return (VM_PAGER_OK);
 	} else if (reqblock == -1) {
 		pmap_zero_page(m[reqpage]);
 		KASSERT(m[reqpage]->dirty == 0,
 		    ("vnode_pager_generic_getpages: page %p is dirty", m));
+		VM_OBJECT_WLOCK(object);
 		m[reqpage]->valid = VM_PAGE_BITS_ALL;
 		for (i = 0; i < count; i++)
 			if (i != reqpage) {
@@ -799,9 +799,11 @@ vnode_pager_generic_getpages(struct vnod
 			}
 		VM_OBJECT_WUNLOCK(object);
 		return (VM_PAGER_OK);
+	} else if (m[reqpage]->valid != 0) {
+		VM_OBJECT_WLOCK(object);
+		m[reqpage]->valid = 0;
+		VM_OBJECT_WUNLOCK(object);
 	}
-	m[reqpage]->valid = 0;
-	VM_OBJECT_WUNLOCK(object);
 
 	/*
 	 * here on direct device I/O


More information about the svn-src-all mailing list