git: e6d30726b97a - stable/15 - kqueue: simplify knote_fdclose()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 13 Apr 2026 04:01:50 UTC
The branch stable/15 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=e6d30726b97a449b584cf65447a983d452f9511a
commit e6d30726b97a449b584cf65447a983d452f9511a
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2026-04-01 22:30:48 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-04-13 03:12:19 +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
(cherry picked from commit ff1050d2a366bd288a6ebbf63f98003272513f92)
---
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 3872fb5862c5..245a18738d86 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2838,7 +2838,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);
@@ -2848,22 +2847,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);
}