Author: kib
Date: Mon Feb  6 11:04:36 2012
New Revision: 231075
URL: http://svn.freebsd.org/changeset/base/231075

Log:
  Current implementations of sync(2) and syncer vnode fsync() VOP uses
  mnt_noasync counter to temporary remove MNTK_ASYNC mount option, which
  is needed to guarantee a synchronous completion of the initiated i/o
  before syscall or VOP return.  Global removal of MNTK_ASYNC option is
  harmful because not only i/o started from corresponding thread becomes
  synchronous, but all i/o is synchronous on the filesystem which is
  initiated during sync(2) or syncer activity.
  
  Instead of removing MNTK_ASYNC from mnt_kern_flag, provide a local
  thread flag to disable async i/o for current thread only. Use the
  opportunity to move DOINGASYNC() macro into sys/vnode.h and
  consistently use it through places which tested for MNTK_ASYNC.
  
  Some testing demonstrated 60-70% improvements in run time for the
  metadata-intensive operations on async-mounted UFS volumes, but still
  with great deviation due to other reasons.
  
  Reviewed by:  mckusick
  Tested by:    scottl
  MFC after:    2 weeks

Modified:
  head/sys/fs/ext2fs/inode.h
  head/sys/fs/nfsclient/nfs_clvnops.c
  head/sys/geom/journal/g_journal.c
  head/sys/kern/vfs_subr.c
  head/sys/kern/vfs_syscalls.c
  head/sys/nfsclient/nfs_vnops.c
  head/sys/sys/proc.h
  head/sys/sys/vnode.h
  head/sys/ufs/ufs/inode.h

Modified: head/sys/fs/ext2fs/inode.h
==============================================================================
--- head/sys/fs/ext2fs/inode.h  Mon Feb  6 10:47:12 2012        (r231074)
+++ head/sys/fs/ext2fs/inode.h  Mon Feb  6 11:04:36 2012        (r231075)
@@ -158,9 +158,6 @@ struct indir {
 #define VTOI(vp)       ((struct inode *)(vp)->v_data)
 #define ITOV(ip)       ((ip)->i_vnode)
 
-/* Check whether the MNTK_ASYNC flag has been set for a mount point */
-#define DOINGASYNC(vp)         ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
-
 /* This overlays the fid structure (see mount.h). */
 struct ufid {
        uint16_t ufid_len;      /* Length of structure. */

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c Mon Feb  6 10:47:12 2012        
(r231074)
+++ head/sys/fs/nfsclient/nfs_clvnops.c Mon Feb  6 11:04:36 2012        
(r231075)
@@ -1376,7 +1376,7 @@ ncl_writerpc(struct vnode *vp, struct ui
                if (ret && !error)
                        error = ret;
        }
-       if (vp->v_mount->mnt_kern_flag & MNTK_ASYNC)
+       if (DOINGASYNC(vp))
                *iomode = NFSWRITE_FILESYNC;
        if (error && NFS_ISV4(vp))
                error = nfscl_maperr(uiop->uio_td, error, (uid_t)0, (gid_t)0);

Modified: head/sys/geom/journal/g_journal.c
==============================================================================
--- head/sys/geom/journal/g_journal.c   Mon Feb  6 10:47:12 2012        
(r231074)
+++ head/sys/geom/journal/g_journal.c   Mon Feb  6 11:04:36 2012        
(r231075)
@@ -2870,7 +2870,7 @@ g_journal_do_switch(struct g_class *clas
        struct mount *mp;
        struct bintime bt;
        char *mountpoint;
-       int error, vfslocked;
+       int error, save, vfslocked;
 
        DROP_GIANT();
        g_topology_lock();
@@ -2932,10 +2932,7 @@ g_journal_do_switch(struct g_class *clas
                        goto next;
                }
 
-               MNT_ILOCK(mp);
-               mp->mnt_noasync++;
-               mp->mnt_kern_flag &= ~MNTK_ASYNC;
-               MNT_IUNLOCK(mp);
+               save = curthread_pflags_set(TDP_SYNCIO);
 
                GJ_TIMER_START(1, &bt);
                vfs_msync(mp, MNT_NOWAIT);
@@ -2950,11 +2947,7 @@ g_journal_do_switch(struct g_class *clas
                            mountpoint, error);
                }
 
-               MNT_ILOCK(mp);
-               mp->mnt_noasync--;
-               if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
-                       mp->mnt_kern_flag |= MNTK_ASYNC;
-               MNT_IUNLOCK(mp);
+               curthread_pflags_restore(save);
 
                vn_finished_write(mp);
 

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c    Mon Feb  6 10:47:12 2012        (r231074)
+++ head/sys/kern/vfs_subr.c    Mon Feb  6 11:04:36 2012        (r231075)
@@ -3521,7 +3521,7 @@ sync_fsync(struct vop_fsync_args *ap)
 {
        struct vnode *syncvp = ap->a_vp;
        struct mount *mp = syncvp->v_mount;
-       int error;
+       int error, save;
        struct bufobj *bo;
 
        /*
@@ -3551,17 +3551,10 @@ sync_fsync(struct vop_fsync_args *ap)
                vfs_unbusy(mp);
                return (0);
        }
-       MNT_ILOCK(mp);
-       mp->mnt_noasync++;
-       mp->mnt_kern_flag &= ~MNTK_ASYNC;
-       MNT_IUNLOCK(mp);
+       save = curthread_pflags_set(TDP_SYNCIO);
        vfs_msync(mp, MNT_NOWAIT);
        error = VFS_SYNC(mp, MNT_LAZY);
-       MNT_ILOCK(mp);
-       mp->mnt_noasync--;
-       if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0)
-               mp->mnt_kern_flag |= MNTK_ASYNC;
-       MNT_IUNLOCK(mp);
+       curthread_pflags_restore(save);
        vn_finished_write(mp);
        vfs_unbusy(mp);
        return (error);

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c        Mon Feb  6 10:47:12 2012        
(r231074)
+++ head/sys/kern/vfs_syscalls.c        Mon Feb  6 11:04:36 2012        
(r231075)
@@ -134,7 +134,7 @@ sys_sync(td, uap)
        struct sync_args *uap;
 {
        struct mount *mp, *nmp;
-       int vfslocked;
+       int save, vfslocked;
 
        mtx_lock(&mountlist_mtx);
        for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
@@ -145,18 +145,10 @@ sys_sync(td, uap)
                vfslocked = VFS_LOCK_GIANT(mp);
                if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
                    vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
-                       MNT_ILOCK(mp);
-                       mp->mnt_noasync++;
-                       mp->mnt_kern_flag &= ~MNTK_ASYNC;
-                       MNT_IUNLOCK(mp);
+                       save = curthread_pflags_set(TDP_SYNCIO);
                        vfs_msync(mp, MNT_NOWAIT);
                        VFS_SYNC(mp, MNT_NOWAIT);
-                       MNT_ILOCK(mp);
-                       mp->mnt_noasync--;
-                       if ((mp->mnt_flag & MNT_ASYNC) != 0 &&
-                           mp->mnt_noasync == 0)
-                               mp->mnt_kern_flag |= MNTK_ASYNC;
-                       MNT_IUNLOCK(mp);
+                       curthread_pflags_restore(save);
                        vn_finished_write(mp);
                }
                VFS_UNLOCK_GIANT(vfslocked);

Modified: head/sys/nfsclient/nfs_vnops.c
==============================================================================
--- head/sys/nfsclient/nfs_vnops.c      Mon Feb  6 10:47:12 2012        
(r231074)
+++ head/sys/nfsclient/nfs_vnops.c      Mon Feb  6 11:04:36 2012        
(r231075)
@@ -1448,7 +1448,7 @@ nfs_writerpc(struct vnode *vp, struct ui
                tsiz -= len;
        }
 nfsmout:
-       if (vp->v_mount->mnt_kern_flag & MNTK_ASYNC)
+       if (DOINGASYNC(vp))
                committed = NFSV3WRITE_FILESYNC;
        *iomode = committed;
        if (error)

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Mon Feb  6 10:47:12 2012        (r231074)
+++ head/sys/sys/proc.h Mon Feb  6 11:04:36 2012        (r231075)
@@ -400,7 +400,7 @@ do {                                                        
                \
 #define        TDP_NOSLEEPING  0x00000100 /* Thread is not allowed to sleep on 
a sq. */
 #define        TDP_OWEUPC      0x00000200 /* Call addupc() at next AST. */
 #define        TDP_ITHREAD     0x00000400 /* Thread is an interrupt thread. */
-#define        TDP_UNUSED800   0x00000800 /* available. */
+#define        TDP_SYNCIO      0x00000800 /* Local override, disable async 
i/o. */
 #define        TDP_SCHED1      0x00001000 /* Reserved for scheduler private 
use */
 #define        TDP_SCHED2      0x00002000 /* Reserved for scheduler private 
use */
 #define        TDP_SCHED3      0x00004000 /* Reserved for scheduler private 
use */

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h        Mon Feb  6 10:47:12 2012        (r231074)
+++ head/sys/sys/vnode.h        Mon Feb  6 11:04:36 2012        (r231075)
@@ -538,6 +538,10 @@ void       assert_vop_unlocked(struct vnode *v
  */
 #define VCALL(c) ((c)->a_desc->vdesc_call(c))
 
+#define DOINGASYNC(vp)                                         \
+       (((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC) != 0 &&    \
+        ((curthread->td_pflags & TDP_SYNCIO) == 0))
+
 /*
  * VMIO support inline
  */

Modified: head/sys/ufs/ufs/inode.h
==============================================================================
--- head/sys/ufs/ufs/inode.h    Mon Feb  6 10:47:12 2012        (r231074)
+++ head/sys/ufs/ufs/inode.h    Mon Feb  6 11:04:36 2012        (r231075)
@@ -176,7 +176,6 @@ struct indir {
 /* Determine if soft dependencies are being done */
 #define DOINGSOFTDEP(vp)   ((vp)->v_mount->mnt_flag & (MNT_SOFTDEP | MNT_SUJ))
 #define MOUNTEDSOFTDEP(mp) ((mp)->mnt_flag & (MNT_SOFTDEP | MNT_SUJ))
-#define DOINGASYNC(vp)    ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
 #define DOINGSUJ(vp)      ((vp)->v_mount->mnt_flag & MNT_SUJ)
 #define MOUNTEDSUJ(mp)    ((mp)->mnt_flag & MNT_SUJ)
 
_______________________________________________
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"

Reply via email to