Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Apr 2026 04:01:53 +0000
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 94429503486f - stable/15 - kqueue: compare against the size in kqueue_expand
Message-ID:  <69dc6ab1.1e959.3738f878@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/15 has been updated by kevans:

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

commit 94429503486f0738b5670b9a203f48fc2bd5fabf
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:33 +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
    
    (cherry picked from commit 0b4f0e0515d0c7ec855cd654ae5dc562f4931cae)
---
 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 915d34ac1695..f3723783146a 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2017,10 +2017,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;
@@ -2028,7 +2029,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) {
@@ -2043,6 +2044,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 {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69dc6ab1.1e959.3738f878>