Module Name: src Committed By: joerg Date: Thu Sep 21 18:19:44 UTC 2017
Modified Files: src/sys/kern: vfs_vnode.c src/sys/sys: vnode_impl.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.98 -r1.99 src/sys/kern/vfs_vnode.c cvs rdiff -u -r1.16 -r1.17 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.98 src/sys/kern/vfs_vnode.c:1.99 --- src/sys/kern/vfs_vnode.c:1.98 Mon Aug 21 09:00:21 2017 +++ src/sys/kern/vfs_vnode.c Thu Sep 21 18:19:44 2017 @@ -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 @@ 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: src/sys/sys/vnode_impl.h diff -u src/sys/sys/vnode_impl.h:1.16 src/sys/sys/vnode_impl.h:1.17 --- src/sys/sys/vnode_impl.h:1.16 Mon Aug 21 09:00:21 2017 +++ src/sys/sys/vnode_impl.h Thu Sep 21 18:19:44 2017 @@ -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 @@ 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) */