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>
