tech-kern archive

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

Performance of VSTATE_ASSERT_UNLOCKED



Hello Juergen,
the new VSTATE_ASSERT_UNLOCKED code you added to genfs_lock is very
heavy as it significantly increases lock contention for something
already highly contended. I'd like to push the lock down to critical
cases and try to avoid it for common cases.

Thoughts?

Joerg
Index: kern/vfs_vnode.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/kern/vfs_vnode.c,v
retrieving revision 1.98
diff -u -p -r1.98 vfs_vnode.c
--- kern/vfs_vnode.c	21 Aug 2017 09:00:21 -0000	1.98
+++ kern/vfs_vnode.c	11 Sep 2017 16:19:04 -0000
@@ -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);
Index: sys/vnode_impl.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/sys/vnode_impl.h,v
retrieving revision 1.16
diff -u -p -r1.16 vnode_impl.h
--- sys/vnode_impl.h	21 Aug 2017 09:00:21 -0000	1.16
+++ sys/vnode_impl.h	11 Sep 2017 15:56:54 -0000
@@ -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) */
 


Home | Main Index | Thread Index | Old Index