Module Name:    src
Committed By:   martin
Date:           Fri Nov 17 14:34:02 UTC 2017

Modified Files:
        src/sys/kern [netbsd-8]: vfs_vnode.c
        src/sys/sys [netbsd-8]: vnode_impl.h

Log Message:
Pull up following revision(s) (requested by hannken in ticket #309):
        sys/sys/vnode_impl.h: revision 1.17
        sys/kern/vfs_vnode.c: revision 1.99, 1.100

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.
-
Fix non-DIAGNOSTICS build by adjusting _vstate_assert here too.


To generate a diff of this commit:
cvs rdiff -u -r1.93.2.2 -r1.93.2.3 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.13.6.2 -r1.13.6.3 src/sys/sys/vnode_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.93.2.2 src/sys/kern/vfs_vnode.c:1.93.2.3
--- src/sys/kern/vfs_vnode.c:1.93.2.2	Fri Aug 25 05:46:46 2017
+++ src/sys/kern/vfs_vnode.c	Fri Nov 17 14:34:02 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.93.2.2 2017/08/25 05:46:46 snj Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.93.2.3 2017/11/17 14:34:02 martin 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.93.2.2 2017/08/25 05:46:46 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.93.2.3 2017/11/17 14:34:02 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -242,17 +242,34 @@ extern struct vfsops	dead_vfsops;
 	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))
-		return;
-	if (vip->vi_state == state)
+	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;
+	}
 	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);
@@ -329,7 +346,8 @@ vstate_assert_change(vnode_t *vp, enum v
 #define VSTATE_WAIT_STABLE(vp) \
 	vstate_wait_stable((vp))
 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)
 {
 
 }

Index: src/sys/sys/vnode_impl.h
diff -u src/sys/sys/vnode_impl.h:1.13.6.2 src/sys/sys/vnode_impl.h:1.13.6.3
--- src/sys/sys/vnode_impl.h:1.13.6.2	Fri Aug 25 05:46:46 2017
+++ src/sys/sys/vnode_impl.h	Fri Nov 17 14:34:02 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnode_impl.h,v 1.13.6.2 2017/08/25 05:46:46 snj Exp $	*/
+/*	$NetBSD: vnode_impl.h,v 1.13.6.3 2017/11/17 14:34:02 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -88,20 +88,14 @@ typedef struct vnode_impl vnode_impl_t;
 /*
  * 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) */
 

Reply via email to