Date: Fri, 07 Aug 2026 23:05:03 +0000 From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih <freebsd@seuros.com> Subject: git: 4c4bad4421fb - main - kqueue: avoid closing a file under the knlist lock Message-ID: <6a76649f.3628b.44c639c6@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=4c4bad4421fb1a300178767f71215cc5f5e0bfb6 commit 4c4bad4421fb1a300178767f71215cc5f5e0bfb6 Author: Abdelkader Boudih <freebsd@seuros.com> AuthorDate: 2026-08-07 22:57:07 +0000 Commit: Adrian Chadd <adrian@FreeBSD.org> CommitDate: 2026-08-07 22:57:11 +0000 kqueue: avoid closing a file under the knlist lock Killing a knote releases its file reference, and releasing the last one runs the close path inline. panic: _mtx_lock_sleep: recursed on non-recursive mutex ttymtx Revoking a controlling tty during exit reaches this whenever a knote is still registered on it. Released the knlist lock around the drop and restart the walk. The knote stays valid while the lock is released. MFC: 1 week Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D58681 --- sys/kern/kern_event.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 507451ce4492..734f8a408f4d 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -2793,6 +2793,7 @@ knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) { struct knote *kn, *kn2; struct kqueue *kq; + bool dropped; KASSERT(!knl->kl_autodestroy, ("cleardel for autodestroy %p", knl)); if (islocked) @@ -2809,6 +2810,7 @@ knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) * freed or converted to one-shot, as the attached subject is * essentially disappearing. */ + dropped = false; SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) { kq = kn->kn_kq; KQ_LOCK(kq); @@ -2820,7 +2822,11 @@ knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) if (killkn) { kn_enter_flux(kn); KQ_UNLOCK(kq); + knl->kl_unlock(knl->kl_lockarg); knote_drop_detached(kn, td); + knl->kl_lock(knl->kl_lockarg); + dropped = true; + break; } else { /* Make sure cleared knotes disappear soon */ kn->kn_flags |= EV_EOF | EV_ONESHOT; @@ -2828,6 +2834,8 @@ knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) } kq = NULL; } + if (dropped) + continue; if (SLIST_EMPTY(&knl->kl_list)) break;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a76649f.3628b.44c639c6>
