The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c6dd40f2d35d596ca60a5d87616c3e4a0fd4f676

commit c6dd40f2d35d596ca60a5d87616c3e4a0fd4f676
Author:     Kyle Evans <[email protected]>
AuthorDate: 2026-04-09 02:37:00 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2026-04-09 02:37:11 +0000

    kqueue: slightly clarify the flow in knlist_cleardel()
    
    This is purely a cosmetic change to make it a little easier on the eyes,
    rather than jumping back to the else branch up top.  Re-flow it to use
    another loop on the outside and just inline the re-lock before we repeat
    after awaking from fluxwait.
    
    The !killkn path should maybe issue a wakeup if there's a thread in
    KQ_SLEEP so that userland can observe the EOF, but this isn't a
    practical problem today: pretty much every case of knlist_clear is tied
    to a file descriptor and called in the close(2) path.  As a consequence,
    potentially affected knotes are almost always destroyed before we even
    get to knlist_clear().
    
    Reviewed by:    kib, markj
    Differential Revision:  https://reviews.freebsd.org/D56226
---
 sys/kern/kern_event.c | 50 +++++++++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 1deb7a705c56..01731ca46b6b 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2792,31 +2792,39 @@ knlist_cleardel(struct knlist *knl, struct thread *td, 
int islocked, int killkn)
                KNL_ASSERT_LOCKED(knl);
        else {
                KNL_ASSERT_UNLOCKED(knl);
-again:         /* need to reacquire lock since we have dropped it */
                knl->kl_lock(knl->kl_lockarg);
        }
 
-       SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) {
-               kq = kn->kn_kq;
-               KQ_LOCK(kq);
-               if (kn_in_flux(kn)) {
-                       KQ_UNLOCK(kq);
-                       continue;
-               }
-               knlist_remove_kq(knl, kn, 1, 1);
-               if (killkn) {
-                       kn_enter_flux(kn);
-                       KQ_UNLOCK(kq);
-                       knote_drop_detached(kn, td);
-               } else {
-                       /* Make sure cleared knotes disappear soon */
-                       kn->kn_flags |= EV_EOF | EV_ONESHOT;
-                       KQ_UNLOCK(kq);
+       for (;;) {
+               /*
+                * Each pass removes as many knotes as we can before dropping
+                * into FLUXWAIT.  Active knotes are simply detached and either
+                * freed or converted to one-shot, as the attached subject is
+                * essentially disappearing.
+                */
+               SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) {
+                       kq = kn->kn_kq;
+                       KQ_LOCK(kq);
+                       if (kn_in_flux(kn)) {
+                               KQ_UNLOCK(kq);
+                               continue;
+                       }
+                       knlist_remove_kq(knl, kn, 1, 1);
+                       if (killkn) {
+                               kn_enter_flux(kn);
+                               KQ_UNLOCK(kq);
+                               knote_drop_detached(kn, td);
+                       } else {
+                               /* Make sure cleared knotes disappear soon */
+                               kn->kn_flags |= EV_EOF | EV_ONESHOT;
+                               KQ_UNLOCK(kq);
+                       }
+                       kq = NULL;
                }
-               kq = NULL;
-       }
 
-       if (!SLIST_EMPTY(&knl->kl_list)) {
+               if (SLIST_EMPTY(&knl->kl_list))
+                       break;
+
                /* there are still in flux knotes remaining */
                kn = SLIST_FIRST(&knl->kl_list);
                kq = kn->kn_kq;
@@ -2826,7 +2834,7 @@ again:            /* need to reacquire lock since we have 
dropped it */
                kq->kq_state |= KQ_FLUXWAIT;
                msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0);
                kq = NULL;
-               goto again;
+               knl->kl_lock(knl->kl_lockarg);
        }
 
        if (islocked)

Reply via email to