The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=d795c753e262b97a93dc353aa66b858e1b1969d1
commit d795c753e262b97a93dc353aa66b858e1b1969d1 Author: Mark Johnston <[email protected]> AuthorDate: 2025-11-18 14:22:04 +0000 Commit: Mark Johnston <[email protected]> CommitDate: 2025-11-18 16:24:21 +0000 kevent: Hold the knlist mutex when invoking f_event(NOTE_FORK) In general f_event is supposed to be called with the knlist mutex held, so lock it earlier to follow this protocol. Also make sure that the update to kn_fflags is synchronized. Lock the kqueue itself earlier in the case where the knote is activated, to avoid locking and unlocking the kqueue twice. PR: 291005 Reported by: Qiu-ji Chen <[email protected]> Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D53762 --- sys/kern/kern_event.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 1baa24d278bf..a48408fd482a 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -627,12 +627,20 @@ knote_fork(struct knlist *list, int pid) kev.data = kn->kn_id; /* parent */ kev.udata = kn->kn_kevent.udata;/* preserve udata */ error = kqueue_register(kq, &kev, NULL, M_NOWAIT); + + /* + * Serialize updates to the kn_kevent fields with threads + * scanning the queue. + */ + list->kl_lock(list->kl_lockarg); if (error) kn->kn_fflags |= NOTE_TRACKERR; - if (kn->kn_fop->f_event(kn, NOTE_FORK)) - KNOTE_ACTIVATE(kn, 0); - list->kl_lock(list->kl_lockarg); - KQ_LOCK(kq); + if (kn->kn_fop->f_event(kn, NOTE_FORK)) { + KQ_LOCK(kq); + KNOTE_ACTIVATE(kn, 1); + } else { + KQ_LOCK(kq); + } kn_leave_flux(kn); KQ_UNLOCK_FLUX(kq); }
