git: 0b4f0e0515d0 - main - kqueue: compare against the size in kqueue_expand
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Apr 2026 22:33:28 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=0b4f0e0515d0c7ec855cd654ae5dc562f4931cae
commit 0b4f0e0515d0c7ec855cd654ae5dc562f4931cae
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: compare against the size in kqueue_expand
This is a cosmetic change, rather than a functional one: comparing the
knlistsize against the fd requires a little bit of mental gymnastics to
confirm that this is fine and not doing unnecessary work in some cases.
Notably, one must consider that kq_knlistsize only grows in KQEXTENT
chunks, which means that concurrent threads trying to grow the kqueue
to consecutive fds will usually not result in the list being replaced
twice. One can also more clearly rule out classes of arithmetic
problems in the final `else` branch.
Reviewed by: kib, markj
Differential Revision: https://reviews.freebsd.org/D56209
---
sys/kern/kern_event.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index f984161bfcd6..2cdc37b710e6 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2013,10 +2013,11 @@ kqueue_expand(struct kqueue *kq, const struct filterops *fops, uintptr_t ident,
to_free = NULL;
if (fops->f_isfd) {
fd = ident;
- if (kq->kq_knlistsize <= fd) {
- size = kq->kq_knlistsize;
- while (size <= fd)
+ size = atomic_load_int(&kq->kq_knlistsize);
+ if (size <= fd) {
+ do {
size += KQEXTENT;
+ } while (size <= fd);
list = malloc(size * sizeof(*list), M_KQUEUE, mflag);
if (list == NULL)
return ENOMEM;
@@ -2024,7 +2025,7 @@ kqueue_expand(struct kqueue *kq, const struct filterops *fops, uintptr_t ident,
if ((kq->kq_state & KQ_CLOSING) != 0) {
to_free = list;
error = EBADF;
- } else if (kq->kq_knlistsize > fd) {
+ } else if (kq->kq_knlistsize >= size) {
to_free = list;
} else {
if (kq->kq_knlist != NULL) {
@@ -2039,6 +2040,7 @@ kqueue_expand(struct kqueue *kq, const struct filterops *fops, uintptr_t ident,
kq->kq_knlistsize = size;
kq->kq_knlist = list;
}
+ MPASS(error != 0 || kq->kq_knlistsize > fd);
KQ_UNLOCK(kq);
}
} else {