diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -162,6 +162,7 @@ vfs_vector_op_register(&crossmp_vnodeops); getnewvnode("crossmp", NULL, &crossmp_vnodeops, &vp_crossmp); vp_crossmp->v_state = VSTATE_CONSTRUCTED; + vp_crossmp->v_irflag |= VIRF_CROSSMP; } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -5452,14 +5452,18 @@ void assert_vop_locked(struct vnode *vp, const char *str) { - int locked; - if (KERNEL_PANICKED() || vp == NULL) return; - locked = VOP_ISLOCKED(vp); +#ifdef WITNESS + if ((vp->v_irflag & VIRF_CROSSMP) == 0) + witness_assert(&vp->v_vnlock->lock_object, LA_LOCKED, + __FILE__, __LINE__); +#else + int locked = VOP_ISLOCKED(vp); if (locked == 0 || locked == LK_EXCLOTHER) vfs_badlock("is not locked but should be", str, vp); +#endif } void @@ -5468,8 +5472,14 @@ if (KERNEL_PANICKED() || vp == NULL) return; +#ifdef WITNESS + if ((vp->v_irflag & VIRF_CROSSMP) == 0) + witness_assert(&vp->v_vnlock->lock_object, LA_UNLOCKED, + __FILE__, __LINE__); +#else if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) vfs_badlock("is locked but should not be", str, vp); +#endif } void diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -228,6 +228,7 @@ never cleared once set */ #define VIRF_MOUNTPOINT 0x0004 /* This vnode is mounted on */ #define VIRF_TEXT_REF 0x0008 /* Executable mappings ref the vnode */ +#define VIRF_CROSSMP 0x0010 /* Cross-mp vnode, no locking */ #define VI_UNUSED0 0x0001 /* unused */ #define VI_MOUNT 0x0002 /* Mount in progress */