Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 01 Apr 2026 22:33:31 +0000
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: ff1050d2a366 - main - kqueue: simplify knote_fdclose()
Message-ID:  <69cd9d3b.43e40.112feed2@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kevans:

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

commit ff1050d2a366bd288a6ebbf63f98003272513f92
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2026-04-01 22:30:48 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-04-01 22:30:48 +0000

    kqueue: simplify knote_fdclose()
    
    The influx logic in knote_fdclose() is a little misguided, the resulting
    wakeup() call should always be redundant: knote_drop_detached() will
    always issue a wakeup before it returns, so anything waiting on *that*
    knote that had entered fluxwait should have been woken up then.  This is
    the obvious divergence from the other influx/wakeup pattern in the
    implementation, which will kn_influx-- and then issue the wakeup after
    it has processed all of the knotes it can make progress on.
    
    While we're here, the kq_knlist cannot shrink, so we can avoid that
    condition in the loop and avoid potentially excessive wakeups from
    fluxwait on kqueues that we didn't touch.
    
    Reviewed by:    kib, markj
    Differential Revision:  https://reviews.freebsd.org/D56210
---
 sys/kern/kern_event.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 6af53cf6cd91..485123989319 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2836,7 +2836,6 @@ knote_fdclose(struct thread *td, int fd)
 	struct filedesc *fdp = td->td_proc->p_fd;
 	struct kqueue *kq;
 	struct knote *kn;
-	int influx;
 
 	FILEDESC_XLOCK_ASSERT(fdp);
 
@@ -2846,22 +2845,25 @@ knote_fdclose(struct thread *td, int fd)
 	 */
 	TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) {
 		KQ_LOCK(kq);
+		if (kq->kq_knlistsize <= fd ||
+		    SLIST_EMPTY(&kq->kq_knlist[fd])) {
+			KQ_UNLOCK(kq);
+			continue;
+		}
 
-again:
-		influx = 0;
-		while (kq->kq_knlistsize > fd &&
-		    (kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) {
+		while ((kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) {
 			if (kn_in_flux(kn)) {
-				/* someone else might be waiting on our knote */
-				if (influx)
-					wakeup(kq);
+				/*
+				 * Wait for this knote to stabilize, it could be
+				 * the case that it's in the process of being
+				 * dropped anyways.
+				 */
 				kq->kq_state |= KQ_FLUXWAIT;
 				msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0);
-				goto again;
+				continue;
 			}
 			kn_enter_flux(kn);
 			KQ_UNLOCK(kq);
-			influx = 1;
 			knote_drop(kn, td);
 			KQ_LOCK(kq);
 		}


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69cd9d3b.43e40.112feed2>