From 6d4a61ca3e1b1ce964410c089eee8382e236a857 Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 23 Dec 2011 09:09:42 +0000 Subject: [PATCH 58/65] 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 git-svn-id: http://svn.freebsd.org/base/head@228838 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f (cherry picked from commit 16b2c818da82583ed83c1a9281a78bf1fbbc38f0) Signed-off-by: Xin Li --- sys/vm/vm_object.c | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 3de793b..7389d0e 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -937,7 +937,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size, vm_object_t backing_object; struct vnode *vp; struct mount *mp; - int flags; + int flags, fsync_after; if (object == NULL) return; @@ -970,11 +970,26 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size, (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); -- 1.7.8.3