git: fee6a52e4338 - main - sysctl_kern_proc_kqueue(): convert to use sbuf
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 24 Mar 2025 02:24:46 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=fee6a52e433811fde5a9f6be06bb446b5336aba3 commit fee6a52e433811fde5a9f6be06bb446b5336aba3 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-03-13 22:30:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2025-03-24 02:24:13 +0000 sysctl_kern_proc_kqueue(): convert to use sbuf Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D49372 --- sys/kern/kern_event.c | 74 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 14aa3abd1901..b0106b5fa9ce 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -58,6 +58,7 @@ #include <sys/poll.h> #include <sys/protosw.h> #include <sys/resourcevar.h> +#include <sys/sbuf.h> #include <sys/sigio.h> #include <sys/signalvar.h> #include <sys/socket.h> @@ -2871,7 +2872,7 @@ knote_status_export(int kn_status) } static int -sysctl_kern_proc_kqueue_report_one(struct proc *p, struct sysctl_req *req, +kern_proc_kqueue_report_one(struct sbuf *s, struct proc *p, struct kqueue *kq, struct knote *kn) { struct kinfo_knote kin; @@ -2887,13 +2888,41 @@ sysctl_kern_proc_kqueue_report_one(struct proc *p, struct sysctl_req *req, KQ_UNLOCK_FLUX(kq); if (kn->kn_fop->f_userdump != NULL) (void)kn->kn_fop->f_userdump(p, kn, &kin); - error = SYSCTL_OUT(req, &kin, sizeof(kin)); - maybe_yield(); + error = sbuf_bcat(s, &kin, sizeof(kin)); KQ_LOCK(kq); kn_leave_flux(kn); return (error); } +static int +kern_proc_kqueue_report(struct sbuf *s, struct proc *p, struct kqueue *kq) +{ + struct knote *kn; + int error, i; + + error = 0; + KQ_LOCK(kq); + for (i = 0; i < kq->kq_knlistsize; i++) { + SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) { + error = kern_proc_kqueue_report_one(s, p, kq, kn); + if (error != 0) + goto out; + } + } + if (kq->kq_knhashmask == 0) + goto out; + for (i = 0; i <= kq->kq_knhashmask; i++) { + SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) { + error = kern_proc_kqueue_report_one(s, p, kq, kn); + if (error != 0) + goto out; + } + } +out: + KQ_UNLOCK_FLUX(kq); + return (error); +} + static int sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS) { @@ -2901,8 +2930,8 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS) struct proc *p; struct file *fp; struct kqueue *kq; - struct knote *kn; - int error, i, *name; + struct sbuf *s, sm; + int error, error1, *name; name = (int *)arg1; if ((u_int)arg2 != 2) @@ -2928,34 +2957,19 @@ sysctl_kern_proc_kqueue(SYSCTL_HANDLER_ARGS) goto out2; } - kq = fp->f_data; - if (req->oldptr == NULL) { - error = SYSCTL_OUT(req, NULL, sizeof(struct kinfo_knote) * - kq->kq_knlistsize * 11 / 10); + s = sbuf_new_for_sysctl(&sm, NULL, 0, req); + if (s == NULL) { + error = ENOMEM; goto out2; } + sbuf_clear_flags(s, SBUF_INCLUDENUL); - KQ_LOCK(kq); - for (i = 0; i < kq->kq_knlistsize; i++) { - SLIST_FOREACH(kn, &kq->kq_knlist[i], kn_link) { - error = sysctl_kern_proc_kqueue_report_one(p, req, - kq, kn); - if (error != 0) - goto out3; - } - } - if (kq->kq_knhashmask == 0) - goto out3; - for (i = 0; i <= kq->kq_knhashmask; i++) { - SLIST_FOREACH(kn, &kq->kq_knhash[i], kn_link) { - error = sysctl_kern_proc_kqueue_report_one(p, req, - kq, kn); - if (error != 0) - goto out3; - } - } -out3: - KQ_UNLOCK_FLUX(kq); + kq = fp->f_data; + error = kern_proc_kqueue_report(s, p, kq); + error1 = sbuf_finish(s); + if (error == 0) + error = error1; + sbuf_delete(s); out2: fdrop(fp, td); out1: