diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e7f1deea0fae..172aa4b4f576 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -162,6 +162,7 @@ nameiinit(void *dummy __unused) 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 index c2b1f71502cd..7e7315f827a1 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -5452,14 +5452,18 @@ assert_vi_unlocked(struct vnode *vp, const char *str) 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 @@ assert_vop_unlocked(struct vnode *vp, const char *str) 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 index 5e3f81de0236..fa889826867e 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -228,6 +228,7 @@ _Static_assert(sizeof(struct vnode) <= 448, "vnode size crosses 448 bytes"); 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 */