git: d795c753e262 - main - kevent: Hold the knlist mutex when invoking f_event(NOTE_FORK)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 18 Nov 2025 16:24:47 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=d795c753e262b97a93dc353aa66b858e1b1969d1
commit d795c753e262b97a93dc353aa66b858e1b1969d1
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-11-18 14:22:04 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
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 <chenqiuji666@gmail.com>
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);
}