Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Make mntvnode_lock per-mount, and address false sharing of s...



details:   https://anonhg.NetBSD.org/src/rev/95277d96890d
branches:  trunk
changeset: 847429:95277d96890d
user:      ad <ad%NetBSD.org@localhost>
date:      Sun Dec 22 19:47:34 2019 +0000

description:
Make mntvnode_lock per-mount, and address false sharing of struct mount.

diffstat:

 external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c |   6 +-
 sys/kern/vfs_mount.c                                    |  70 +++++++++-------
 sys/kern/vfs_subr.c                                     |  17 ++-
 sys/kern/vfs_syscalls.c                                 |  18 ++--
 sys/miscfs/genfs/genfs_vfsops.c                         |  10 +-
 sys/nfs/nfs_export.c                                    |  14 +-
 sys/sys/mount.h                                         |  23 +++-
 sys/sys/vnode.h                                         |   7 +-
 sys/sys/vnode_impl.h                                    |   4 +-
 sys/ufs/lfs/ulfs_vfsops.c                               |  12 +-
 sys/ufs/ufs/ufs_vfsops.c                                |  12 +-
 sys/ufs/ufs/ufs_wapbl.c                                 |  22 ++--
 12 files changed, 116 insertions(+), 99 deletions(-)

diffs (truncated from 758 to 300 lines):

diff -r 5967c8fb5569 -r 95277d96890d external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c
--- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c   Sun Dec 22 19:19:43 2019 +0000
+++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ctldir.c   Sun Dec 22 19:47:34 2019 +0000
@@ -1329,7 +1329,7 @@
        vfsp->mnt_stat.f_owner = 0;
        vfsp->mnt_flag = MNT_RDONLY | MNT_NOSUID | MNT_IGNORE;
 
-       mutex_enter(&vfsp->mnt_updating);
+       mutex_enter(vfsp->mnt_updating);
 
        error = zfs_domount(vfsp, osname);
        if (error)
@@ -1349,12 +1349,12 @@
        vref(vp);
        vp->v_mountedhere = vfsp;
 
-       mutex_exit(&vfsp->mnt_updating);
+       mutex_exit(vfsp->mnt_updating);
        (void) VFS_STATVFS(vfsp, &vfsp->mnt_stat);
 
 out:;
        if (error && vfsp) {
-               mutex_exit(&vfsp->mnt_updating);
+               mutex_exit(vfsp->mnt_updating);
                vfs_rele(vfsp);
        }
        PNBUF_PUT(osname);
diff -r 5967c8fb5569 -r 95277d96890d sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c      Sun Dec 22 19:19:43 2019 +0000
+++ b/sys/kern/vfs_mount.c      Sun Dec 22 19:47:34 2019 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: vfs_mount.c,v 1.72 2019/11/16 10:07:53 maxv Exp $      */
+/*     $NetBSD: vfs_mount.c,v 1.73 2019/12/22 19:47:34 ad Exp $        */
 
 /*-
- * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.72 2019/11/16 10:07:53 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.73 2019/12/22 19:47:34 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -116,17 +116,16 @@
 
 /* Mounted filesystem list. */
 static TAILQ_HEAD(mountlist, mountlist_entry) mountlist;
-static kmutex_t                        mountlist_lock;
+static kmutex_t                        mountlist_lock __cacheline_aligned;
 int vnode_offset_next_by_lru   /* XXX: ugly hack for pstat.c */
     = offsetof(vnode_impl_t, vi_lrulist.tqe_next);
 
-kmutex_t                       mntvnode_lock;
-kmutex_t                       vfs_list_lock;
+kmutex_t                       vfs_list_lock __cacheline_aligned;
 
 static specificdata_domain_t   mount_specificdata_domain;
 static kmutex_t                        mntid_lock;
 
-static kmutex_t                        mountgen_lock;
+static kmutex_t                        mountgen_lock __cacheline_aligned;
 static uint64_t                        mountgen;
 
 void
@@ -135,7 +134,6 @@
 
        TAILQ_INIT(&mountlist);
        mutex_init(&mountlist_lock, MUTEX_DEFAULT, IPL_NONE);
-       mutex_init(&mntvnode_lock, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&vfs_list_lock, MUTEX_DEFAULT, IPL_NONE);
 
        mount_specificdata_domain = specificdata_domain_create();
@@ -154,8 +152,9 @@
        mp->mnt_op = vfsops;
        mp->mnt_refcnt = 1;
        TAILQ_INIT(&mp->mnt_vnodelist);
-       mutex_init(&mp->mnt_renamelock, MUTEX_DEFAULT, IPL_NONE);
-       mutex_init(&mp->mnt_updating, MUTEX_DEFAULT, IPL_NONE);
+       mp->mnt_renamelock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+       mp->mnt_vnodelock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+       mp->mnt_updating = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
        mp->mnt_vnodecovered = vp;
        mount_initspecific(mp);
 
@@ -292,8 +291,9 @@
         */
        KASSERT(mp->mnt_refcnt == 0);
        specificdata_fini(mount_specificdata_domain, &mp->mnt_specdataref);
-       mutex_destroy(&mp->mnt_updating);
-       mutex_destroy(&mp->mnt_renamelock);
+       mutex_obj_free(mp->mnt_updating);
+       mutex_obj_free(mp->mnt_renamelock);
+       mutex_obj_free(mp->mnt_vnodelock);
        if (mp->mnt_op != NULL) {
                vfs_delref(mp->mnt_op);
        }
@@ -378,10 +378,10 @@
        vp = vnalloc_marker(mp);
        vip = VNODE_TO_VIMPL(vp);
 
-       mutex_enter(&mntvnode_lock);
+       mutex_enter(mp->mnt_vnodelock);
        TAILQ_INSERT_HEAD(&mp->mnt_vnodelist, vip, vi_mntvnodes);
        vp->v_usecount = 1;
-       mutex_exit(&mntvnode_lock);
+       mutex_exit(mp->mnt_vnodelock);
 
        *vnip = (struct vnode_iterator *)vip;
 }
@@ -391,14 +391,16 @@
 {
        vnode_impl_t *mvip = &vni->vi_vnode;
        vnode_t *mvp = VIMPL_TO_VNODE(mvip);
+       kmutex_t *lock;
 
-       mutex_enter(&mntvnode_lock);
        KASSERT(vnis_marker(mvp));
        if (mvp->v_usecount != 0) {
+               lock = mvp->v_mount->mnt_vnodelock;
+               mutex_enter(lock);
                TAILQ_REMOVE(&mvp->v_mount->mnt_vnodelist, mvip, vi_mntvnodes);
                mvp->v_usecount = 0;
+               mutex_exit(lock);
        }
-       mutex_exit(&mntvnode_lock);
        vnfree_marker(mvp);
 }
 
@@ -410,18 +412,20 @@
        struct mount *mp = VIMPL_TO_VNODE(mvip)->v_mount;
        vnode_t *vp;
        vnode_impl_t *vip;
+       kmutex_t *lock;
        int error;
 
        KASSERT(vnis_marker(VIMPL_TO_VNODE(mvip)));
 
+       lock = mp->mnt_vnodelock;
        do {
-               mutex_enter(&mntvnode_lock);
+               mutex_enter(lock);
                vip = TAILQ_NEXT(mvip, vi_mntvnodes);
                TAILQ_REMOVE(&mp->mnt_vnodelist, mvip, vi_mntvnodes);
                VIMPL_TO_VNODE(mvip)->v_usecount = 0;
 again:
                if (vip == NULL) {
-                       mutex_exit(&mntvnode_lock);
+                       mutex_exit(lock);
                        return NULL;
                }
                vp = VIMPL_TO_VNODE(vip);
@@ -437,7 +441,7 @@
 
                TAILQ_INSERT_AFTER(&mp->mnt_vnodelist, vip, mvip, vi_mntvnodes);
                VIMPL_TO_VNODE(mvip)->v_usecount = 1;
-               mutex_exit(&mntvnode_lock);
+               mutex_exit(lock);
                error = vcache_vget(vp);
                KASSERT(error == 0 || error == ENOENT);
        } while (error != 0);
@@ -461,24 +465,32 @@
 {
        vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
        struct mount *omp;
+       kmutex_t *lock;
 
        KASSERT(mp == NULL || (mp->mnt_iflag & IMNT_UNMOUNT) == 0 ||
            vp->v_tag == VT_VFS);
 
-       mutex_enter(&mntvnode_lock);
        /*
         * Delete from old mount point vnode list, if on one.
         */
-       if ((omp = vp->v_mount) != NULL)
+       if ((omp = vp->v_mount) != NULL) {
+               lock = omp->mnt_vnodelock;
+               mutex_enter(lock);
                TAILQ_REMOVE(&vp->v_mount->mnt_vnodelist, vip, vi_mntvnodes);
+               mutex_exit(lock);
+       }
+
        /*
         * Insert into list of vnodes for the new mount point, if
         * available.  The caller must take a reference on the mount
         * structure and donate to the vnode.
         */
-       if ((vp->v_mount = mp) != NULL)
+       if ((vp->v_mount = mp) != NULL) {
+               lock = mp->mnt_vnodelock;
+               mutex_enter(lock);
                TAILQ_INSERT_TAIL(&mp->mnt_vnodelist, vip, vi_mntvnodes);
-       mutex_exit(&mntvnode_lock);
+               mutex_exit(lock);
+       }
 
        if (omp != NULL) {
                /* Release reference to old mount. */
@@ -753,7 +765,7 @@
         */
        mp->mnt_flag = flags & (MNT_BASIC_FLAGS | MNT_FORCE | MNT_IGNORE);
 
-       mutex_enter(&mp->mnt_updating);
+       mutex_enter(mp->mnt_updating);
        error = VFS_MOUNT(mp, path, data, data_len);
        mp->mnt_flag &= ~MNT_OP_FLAGS;
 
@@ -802,7 +814,7 @@
        vput(nd.ni_vp);
 
        mount_checkdirs(vp);
-       mutex_exit(&mp->mnt_updating);
+       mutex_exit(mp->mnt_updating);
 
        /* Hold an additional reference to the mount across VFS_START(). */
        vfs_ref(mp);
@@ -825,7 +837,7 @@
 
 err_unmounted:
        vp->v_mountedhere = NULL;
-       mutex_exit(&mp->mnt_updating);
+       mutex_exit(mp->mnt_updating);
        vfs_rele(mp);
 
        return error;
@@ -863,7 +875,7 @@
        used_extattr = mp->mnt_flag & MNT_EXTATTR;
 
        mp->mnt_iflag |= IMNT_UNMOUNT;
-       mutex_enter(&mp->mnt_updating);
+       mutex_enter(mp->mnt_updating);
        async = mp->mnt_flag & MNT_ASYNC;
        mp->mnt_flag &= ~MNT_ASYNC;
        cache_purgevfs(mp);     /* remove cache entries for this file sys */
@@ -881,7 +893,7 @@
                if ((mp->mnt_flag & (MNT_RDONLY | MNT_ASYNC)) == 0)
                        vfs_syncer_add_to_worklist(mp);
                mp->mnt_flag |= async;
-               mutex_exit(&mp->mnt_updating);
+               mutex_exit(mp->mnt_updating);
                if (!was_suspended)
                        vfs_resume(mp);
                if (used_extattr) {
@@ -892,7 +904,7 @@
                }
                return (error);
        }
-       mutex_exit(&mp->mnt_updating);
+       mutex_exit(mp->mnt_updating);
 
        /*
         * mark filesystem as gone to prevent further umounts
diff -r 5967c8fb5569 -r 95277d96890d sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c       Sun Dec 22 19:19:43 2019 +0000
+++ b/sys/kern/vfs_subr.c       Sun Dec 22 19:47:34 2019 +0000
@@ -1,7 +1,8 @@
-/*     $NetBSD: vfs_subr.c,v 1.477 2019/12/15 20:30:03 joerg Exp $     */
+/*     $NetBSD: vfs_subr.c,v 1.478 2019/12/22 19:47:34 ad Exp $        */
 
 /*-
- * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019
+ *     The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -68,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.477 2019/12/15 20:30:03 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.478 2019/12/22 19:47:34 ad Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -667,13 +668,13 @@
 
        KASSERT(mutex_owned(vp->v_interlock));
 
-       mutex_enter(&syncer_data_lock);
        if (vp->v_iflag & VI_ONWORKLST) {
+               mutex_enter(&syncer_data_lock);
                vp->v_iflag &= ~VI_ONWORKLST;
                slp = &syncer_workitem_pending[vip->vi_synclist_slot];
                TAILQ_REMOVE(slp, vip, vi_synclist);
+               mutex_exit(&syncer_data_lock);
        }
-       mutex_exit(&syncer_data_lock);
 }
 
 /*
@@ -685,7 +686,7 @@
        static int start, incr, next;
        int vdelay;
 



Home | Main Index | Thread Index | Old Index