Source-Changes-HG archive

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

[src/trunk]: src/sys Change the VSTATE_ASSERT_UNLOCKED code by pushing the po...



details:   https://anonhg.NetBSD.org/src/rev/a939ba059a46
branches:  trunk
changeset: 356366:a939ba059a46
user:      joerg <joerg%NetBSD.org@localhost>
date:      Thu Sep 21 18:19:44 2017 +0000

description:
Change the VSTATE_ASSERT_UNLOCKED code by pushing the potential lock
handling into the backend and doing an optimistic (unlocked) check
first. Always taking the vnode interlock makes this assertion otherwise
very heavy for multi-processor machines. Ride the kernel version bump.

diffstat:

 sys/kern/vfs_vnode.c |  31 ++++++++++++++++++++++++-------
 sys/sys/vnode_impl.h |  14 ++++----------
 2 files changed, 28 insertions(+), 17 deletions(-)

diffs (91 lines):

diff -r a8258a63b49e -r a939ba059a46 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Thu Sep 21 11:42:17 2017 +0000
+++ b/sys/kern/vfs_vnode.c      Thu Sep 21 18:19:44 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_vnode.c,v 1.98 2017/08/21 09:00:21 hannken Exp $   */
+/*     $NetBSD: vfs_vnode.c,v 1.99 2017/09/21 18:19:44 joerg Exp $     */
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -156,7 +156,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.98 2017/08/21 09:00:21 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.99 2017/09/21 18:19:44 joerg Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -242,17 +242,34 @@
        vstate_assert_wait_stable((vp), __func__, __LINE__)
 
 void
-_vstate_assert(vnode_t *vp, enum vnode_state state, const char *func, int line)
+_vstate_assert(vnode_t *vp, enum vnode_state state, const char *func, int line,
+    bool has_lock)
 {
        vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
 
+       if (!has_lock) {
+               /*
+                * Prevent predictive loads from the CPU, but check the state
+                * without loooking first.
+                */
+               membar_enter();
+               if (state == VS_ACTIVE && vp->v_usecount > 0 &&
+                   (vip->vi_state == VS_LOADED || vip->vi_state == VS_BLOCKED))
+                       return;
+               if (vip->vi_state == state)
+                       return;
+               mutex_enter((vp)->v_interlock);
+       }
+
        KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
 
-       if (state == VS_ACTIVE && vp->v_usecount > 0 &&
-           (vip->vi_state == VS_LOADED || vip->vi_state == VS_BLOCKED))
+       if ((state == VS_ACTIVE && vp->v_usecount > 0 &&
+           (vip->vi_state == VS_LOADED || vip->vi_state == VS_BLOCKED)) ||
+           vip->vi_state == state) {
+               if (!has_lock)
+                       mutex_exit((vp)->v_interlock);
                return;
-       if (vip->vi_state == state)
-               return;
+       }
        vnpanic(vp, "state is %s, usecount %d, expected %s at %s:%d",
            vstate_name(vip->vi_state), vp->v_usecount,
            vstate_name(state), func, line);
diff -r a8258a63b49e -r a939ba059a46 sys/sys/vnode_impl.h
--- a/sys/sys/vnode_impl.h      Thu Sep 21 11:42:17 2017 +0000
+++ b/sys/sys/vnode_impl.h      Thu Sep 21 18:19:44 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vnode_impl.h,v 1.16 2017/08/21 09:00:21 hannken Exp $  */
+/*     $NetBSD: vnode_impl.h,v 1.17 2017/09/21 18:19:44 joerg Exp $    */
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -88,20 +88,14 @@
 /*
  * Vnode state assertion.
  */
-void _vstate_assert(vnode_t *, enum vnode_state, const char *, int );
+void _vstate_assert(vnode_t *, enum vnode_state, const char *, int, bool);
 
 #if defined(DIAGNOSTIC) 
 
 #define VSTATE_ASSERT(vp, state) \
-       do { \
-               _vstate_assert((vp), (state), __func__, __LINE__); \
-       } while (/*CONSTCOND*/ 0)
+       _vstate_assert((vp), (state), __func__, __LINE__, true)
 #define VSTATE_ASSERT_UNLOCKED(vp, state) \
-       do { \
-               mutex_enter((vp)->v_interlock); \
-               _vstate_assert((vp), (state), __func__, __LINE__); \
-               mutex_exit((vp)->v_interlock); \
-       } while (/*CONSTCOND*/ 0)
+       _vstate_assert((vp), (state), __func__, __LINE__, false)
 
 #else /* defined(DIAGNOSTIC) */
 



Home | Main Index | Thread Index | Old Index