Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Dec 2011 09:09:43 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r228838 - head/sys/vm
Message-ID:  <201112230909.pBN99hZB056993@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Dec 23 09:09:42 2011
New Revision: 228838
URL: http://svn.freebsd.org/changeset/base/228838

Log:
  Optimize the common case of msyncing the whole file mapping with
  MS_SYNC flag. The system must guarantee that all writes are finished
  before syscalls returned. Schedule the writes in async mode, which is
  much faster and allows the clustering to occur. Wait for writes using
  VOP_FSYNC(), since we are syncing the whole file mapping.
  
  Potentially, the restriction to only apply the optimization can be
  relaxed by not requiring that the mapping cover whole file, as it is
  done by other OSes.
  
  Reported and tested by:	 az
  Reviewed by: alc
  MFC after:   2 weeks

Modified:
  head/sys/vm/vm_object.c

Modified: head/sys/vm/vm_object.c
==============================================================================
--- head/sys/vm/vm_object.c	Fri Dec 23 09:09:10 2011	(r228837)
+++ head/sys/vm/vm_object.c	Fri Dec 23 09:09:42 2011	(r228838)
@@ -938,7 +938,7 @@ vm_object_sync(vm_object_t object, vm_oo
 	vm_object_t backing_object;
 	struct vnode *vp;
 	struct mount *mp;
-	int flags;
+	int flags, fsync_after;
 
 	if (object == NULL)
 		return;
@@ -971,11 +971,26 @@ vm_object_sync(vm_object_t object, vm_oo
 		(void) vn_start_write(vp, &mp, V_WAIT);
 		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-		flags = (syncio || invalidate) ? OBJPC_SYNC : 0;
-		flags |= invalidate ? OBJPC_INVAL : 0;
+		if (syncio && !invalidate && offset == 0 &&
+		    OFF_TO_IDX(size) == object->size) {
+			/*
+			 * If syncing the whole mapping of the file,
+			 * it is faster to schedule all the writes in
+			 * async mode, also allowing the clustering,
+			 * and then wait for i/o to complete.
+			 */
+			flags = 0;
+			fsync_after = TRUE;
+		} else {
+			flags = (syncio || invalidate) ? OBJPC_SYNC : 0;
+			flags |= invalidate ? (OBJPC_SYNC | OBJPC_INVAL) : 0;
+			fsync_after = FALSE;
+		}
 		VM_OBJECT_LOCK(object);
 		vm_object_page_clean(object, offset, offset + size, flags);
 		VM_OBJECT_UNLOCK(object);
+		if (fsync_after)
+			(void) VOP_FSYNC(vp, MNT_WAIT, curthread);
 		VOP_UNLOCK(vp, 0);
 		VFS_UNLOCK_GIANT(vfslocked);
 		vn_finished_write(mp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112230909.pBN99hZB056993>