Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 May 2026 19:41:19 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 295614] tun_destroy() holds ifnet_detach_sxlock while sleeping on tun_cv
Message-ID:  <bug-295614-227-37ENXo8h1r@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-295614-227@https.bugs.freebsd.org/bugzilla/>

index | next in thread | previous in thread | raw e-mail

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295614

--- Comment #6 from Olivier Cochard <olivier@freebsd.org> ---
(In reply to Kyle Evans from comment #5)
I dug into the git history to make sure I wasn't proposing something that had
already been litigated.

The revert you may be thinking of is r186497 (Qing Li, Dec 2008), which backed
out r186483 (Kip Macy)'s TUN_CLOSED refinement on top of Qing Li's earlier
r186391 cv_wait. The failure mode there was specific: `ifconfig tun0 create`
without ever open(2)'ing the device left TUN_CLOSED never set, so a subsequent
destroy blocked
on the cv forever for an *idle* tun.

That failure mode doesn't apply to the current code. tun_busy is incremented in
tun_busy_locked() (if_tuntap.c:363), called from tunopen() at line 1192, i.e.
only when something actually open(2)s /dev/tunN. An idle never-opened tun has
tun_busy == 0 and the EBUSY check in my patch doesn't fire. The four-line
create/configure/route/destroy recipe Qing Li worried about still works.

I read your 274bf7c8ae7e (Aug 2025) commit message as endorsing exactly the
direction this patch goes, "there's no good justification to permanently hang a
thread until the tunnel can be destroyed." The wrinkle on 16-CURRENT is that
the hang takes ifnet_detach_sxlock down with it (held exclusively by
if_clone_destroyif at if_clone.c:480), so any caller who runs `ifconfig tunN
destroy` while a long-lived consumer (e.g. openvpn parked in select) holds the
fd open wedges every subsequent cloner destroy on the host plus jail -R via
tuntap_prison_remove.
Without DEADLKRES compiled in there's no userspace recovery; on a debug kernel
DEADLKRES eventually panics the host.

One observation I'd like to flag but not lean on: on the wedged host, kill -9
on the parked ifconfig did not break the cv_wait_sig, the process stayed in
state S on wchan tun_cond.
One data point, no dtrace, I haven't traced why. So I'm not asserting the
interruptibility is broken in general; only that in the wedge I hit it didn't
help.
Happy to try to reproduce cleanly on a debug kernel if it matters for the
decision. EBUSY-at-entry sidesteps the question either way.

The may_intr=false (tun_uninit) path is left alone, so module unload still
drains as before, only the if_clone_destroyif path changes behavior.

-- 
You are receiving this mail because:
You are the assignee for the bug.

home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-295614-227-37ENXo8h1r>