git: ff1050d2a366 - main - kqueue: simplify knote_fdclose()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Apr 2026 22:33:31 UTC
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);
}