git: b35a7db4829a - stable/15 - kqueue: Allocate marker knotes on the stack
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 06 Aug 2026 15:01:36 UTC
The branch stable/15 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=b35a7db4829ab9826bc428fc3ceaa766bbc0f519
commit b35a7db4829ab9826bc428fc3ceaa766bbc0f519
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-24 20:06:40 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-06 13:24:42 +0000
kqueue: Allocate marker knotes on the stack
The scan marker was originally stack-allocated. In commit
1c0f9af5b5224, it became heap-allocated since the marker is visible to
other threads and a scanning thread's stack may be swapped out. Now
that kernel stacks can no longer be swapped out, we can avoid these heap
allocations.
Reviewed by: kib
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58402
(cherry picked from commit bb933b1d1846b3a984670b8cd65450c3333188f6)
---
sys/kern/kern_event.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 2a1269ec6e3c..cbed1073fa58 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -2112,7 +2112,7 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
const struct timespec *tsp, struct kevent *keva, struct thread *td)
{
struct kevent *kevp;
- struct knote *kn, *marker;
+ struct knote *kn, marker;
struct knlist *knl;
sbintime_t asbt, rsbt;
int count, error, haskqglobal, influx, nkev, touch;
@@ -2151,8 +2151,8 @@ kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops,
asbt = -1;
} else
asbt = 0;
- marker = knote_alloc(M_WAITOK);
- marker->kn_status = KN_MARKER;
+ memset(&marker, 0, sizeof(marker));
+ marker.kn_status = KN_MARKER;
KQ_LOCK(kq);
retry:
@@ -2175,13 +2175,13 @@ retry:
goto done;
}
- TAILQ_INSERT_TAIL(&kq->kq_head, marker, kn_tqe);
+ TAILQ_INSERT_TAIL(&kq->kq_head, &marker, kn_tqe);
influx = 0;
while (count) {
KQ_OWNED(kq);
kn = TAILQ_FIRST(&kq->kq_head);
- if ((kn->kn_status == KN_MARKER && kn != marker) ||
+ if ((kn->kn_status == KN_MARKER && kn != &marker) ||
kn_in_flux(kn)) {
if (influx) {
influx = 0;
@@ -2199,7 +2199,7 @@ retry:
kq->kq_count--;
continue;
}
- if (kn == marker) {
+ if (kn == &marker) {
KQ_FLUX_WAKEUP(kq);
if (count == maxevents)
goto retry;
@@ -2297,11 +2297,10 @@ retry:
break;
}
}
- TAILQ_REMOVE(&kq->kq_head, marker, kn_tqe);
+ TAILQ_REMOVE(&kq->kq_head, &marker, kn_tqe);
done:
KQ_OWNED(kq);
KQ_UNLOCK_FLUX(kq);
- knote_free(marker);
done_nl:
KQ_NOTOWNED(kq);
if (nkev != 0)
@@ -3178,7 +3177,7 @@ kqueue_fork_copy(struct filedesc *fdp, struct file *fp, struct file *fp1,
struct proc *p1, struct thread *td)
{
struct kqueue *kq, *kq1;
- struct knote *marker;
+ struct knote marker;
int error, i;
error = 0;
@@ -3187,26 +3186,24 @@ kqueue_fork_copy(struct filedesc *fdp, struct file *fp, struct file *fp1,
kq1 = fp1->f_data;
kq = kq1->kq_forksrc;
- marker = knote_alloc(M_WAITOK);
- marker->kn_status = KN_MARKER;
- marker->kn_kq = kq;
+ memset(&marker, 0, sizeof(marker));
+ marker.kn_status = KN_MARKER;
+ marker.kn_kq = kq;
KQ_LOCK(kq);
for (i = 0; i < kq->kq_knlistsize; i++) {
- kqueue_fork_copy_list(&kq->kq_knlist[i], marker, kq, kq1,
+ kqueue_fork_copy_list(&kq->kq_knlist[i], &marker, kq, kq1,
p1, fdp);
}
if (kq->kq_knhashmask != 0) {
for (i = 0; i <= kq->kq_knhashmask; i++) {
- kqueue_fork_copy_list(&kq->kq_knhash[i], marker, kq,
+ kqueue_fork_copy_list(&kq->kq_knhash[i], &marker, kq,
kq1, p1, fdp);
}
}
kqueue_release(kq, 1);
kq1->kq_forksrc = NULL;
KQ_UNLOCK_FLUX(kq);
-
- knote_free(marker);
return (error);
}