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);
        }

Reply via email to