A zfs vs. tmpfs lock order reversal during poudriere-devel bulk, nullfs_unmount and tmpfs_unmount involved

From: Mark Millard <marklmi_at_yahoo.com>
Date: Sun, 26 Jul 2026 00:56:53 UTC
After a poudriere-devle bulk run via ssh I later noticed the machine
display was showing a lock order reversal. The dmesg -a output of it is:

lock order reversal:
 1st 0xfffff8012c8a5750 zfs (zfs, lockmgr) @
/usr/src/sys/kern/vfs_mount.c:2308
 2nd 0xfffff80687a3a3e0 tmpfs (tmpfs, lockmgr) @
/usr/src/sys/kern/vfs_subr.c:4205
lock order tmpfs -> zfs established at:
#0 0xffffffff80c8dffa at witness_checkorder+0x36a
#1 0xffffffff80bdb301 at lockmgr_xlock+0x51
#2 0xffffffff8127a252 at VOP_LOCK1_APV+0x32
#3 0xffffffff837ce484 at null_lock+0x174
#4 0xffffffff8127a252 at VOP_LOCK1_APV+0x32
#5 0xffffffff837ce484 at null_lock+0x174
#6 0xffffffff8127a252 at VOP_LOCK1_APV+0x32
#7 0xffffffff80d40ab2 at _vn_lock+0x62
#8 0xffffffff80d24d59 at vflush+0xf9
#9 0xffffffff837cd040 at nullfs_unmount+0x50
#10 0xffffffff80d1848d at dounmount+0x67d
#11 0xffffffff80d17db9 at kern_unmount+0x379
#12 0xffffffff811a13ec at amd64_syscall+0x17c
#13 0xffffffff8116e79b at fast_syscall_common+0xf8
lock order zfs -> tmpfs attempted at:
#0 0xffffffff80c8e9cb at witness_checkorder+0xd3b
#1 0xffffffff80bd99ba at lockmgr_lock_flags+0x16a
#2 0xffffffff8127a252 at VOP_LOCK1_APV+0x32
#3 0xffffffff80d40ab2 at _vn_lock+0x62
#4 0xffffffff80d24d59 at vflush+0xf9
#5 0xffffffff80b25be0 at tmpfs_unmount+0x70
#6 0xffffffff80d1848d at dounmount+0x67d
#7 0xffffffff80d17db9 at kern_unmount+0x379
#8 0xffffffff811a13ec at amd64_syscall+0x17c
#9 0xffffffff8116e79b at fast_syscall_common+0xf8


For reference:


int
dounmount(struct mount *mp, uint64_t flags, struct thread *td)
. . .
       /* Allow the taskqueue to safely re-enqueue on failure */
        if ((flags & MNT_DEFERRED) != 0)
                vfs_ref(mp);

        if ((coveredvp = mp->mnt_vnodecovered) != NULL) {
                mnt_gen_r = mp->mnt_gen;
                VI_LOCK(coveredvp);
                vholdl(coveredvp);
                vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY);

vs.

int
vflush(struct mount *mp, int rootrefs, int flags, struct thread *td)
{
. . .
loop:
        MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
                vholdl(vp);
                error = vn_lock(vp, LK_INTERLOCK | LK_EXCLUSIVE);



The context is almost a recent pkgbase distribution of main:

main-n287650-a594783bac90: /boot/kernel/kernel	FreeBSD 16.0-CURRENT

But it had a boot crash problem with my not having
wifi-firmware-rtw89-kmod-rtw8852b installed. bz@ had me try the patch
from https://reviews.freebsd.org/D57430 applied to the /usr/src/sys/
from that pkgbase distribution. That kernel build and additional kernel
installation avoided the boot crash and is what was (and is) in use:

# uname -apKU
FreeBSD 7950X3D-ZFS 16.0-CURRENT FreeBSD 16.0-CURRENT #1: Sat Jul 25
14:04:54 PDT 2026
root@7950X3D-ZFS:/usr/obj/BUILDs/main-amd64-usr_src-dbg-clang/usr/src/amd64.amd64/sys/GENERIC
amd64 amd64 1600019 1600019


I make no claim to know if this is one of the lock order reversals that
is considered normal.


-- 
===
Mark Millard
marklmi at yahoo.com