aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_event.c10
1 files 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 {