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/7697f1f2c6e3
branches:  trunk
changeset: 826667:7697f1f2c6e3
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 db292cc16543 -r 7697f1f2c6e3 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 db292cc16543 -r 7697f1f2c6e3 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