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) */