From owner-svn-src-head@FreeBSD.ORG Mon Feb 6 11:04:36 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D978B1065670; Mon, 6 Feb 2012 11:04:36 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BE6198FC0C; Mon, 6 Feb 2012 11:04:36 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q16B4aMX032963; Mon, 6 Feb 2012 11:04:36 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q16B4aSp032953; Mon, 6 Feb 2012 11:04:36 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201202061104.q16B4aSp032953@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 6 Feb 2012 11:04:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231075 - in head/sys: fs/ext2fs fs/nfsclient geom/journal kern nfsclient sys ufs/ufs X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Feb 2012 11:04:36 -0000 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)