git: 845896655815 - main - bpf: calculate net.bpf.stats buffer size dynamically
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 03 Dec 2025 23:20:01 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=845896655815eaf339953e2aa48d79ca4539874b
commit 845896655815eaf339953e2aa48d79ca4539874b
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-12-03 23:16:33 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-12-03 23:19:45 +0000
bpf: calculate net.bpf.stats buffer size dynamically
This removed the global counter, that was updated in a racy manner.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D53868
---
sys/net/bpf.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index f5302059d5eb..aff0d3c761ad 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -178,7 +178,6 @@ struct bpf_dltlist32 {
CK_LIST_HEAD(bpf_iflist, bpf_if);
static struct bpf_iflist bpf_iflist = CK_LIST_HEAD_INITIALIZER();
static struct sx bpf_sx; /* bpf global lock */
-static int bpf_bpfd_cnt;
static void bpfif_ref(struct bpf_if *);
static void bpfif_rele(struct bpf_if *);
@@ -760,7 +759,6 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
bpf_wakeup(d);
BPFD_UNLOCK(d);
- bpf_bpfd_cnt++;
CTR3(KTR_NET, "%s: bpf_attach called by pid %d, adding to %s list",
__func__, d->bd_pid, d->bd_writer ? "writer" : "active");
@@ -864,7 +862,6 @@ bpf_detachd(struct bpf_d *d, bool detached_ifp)
bpf_wakeup(d);
}
BPFD_UNLOCK(d);
- bpf_bpfd_cnt--;
/* Call event handler iff d is attached */
if (error == 0)
@@ -3044,7 +3041,8 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
{
static const struct xbpf_d zerostats;
struct xbpf_d *xbdbuf, *xbd, tempstats;
- int index, error;
+ u_int bpfd_cnt, index;
+ int error;
struct bpf_if *bp;
struct bpf_d *bd;
@@ -3074,25 +3072,33 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS)
bpf_zero_counters();
return (0);
}
- if (req->oldptr == NULL)
- return (SYSCTL_OUT(req, 0, bpf_bpfd_cnt * sizeof(*xbd)));
- if (bpf_bpfd_cnt == 0)
- return (SYSCTL_OUT(req, 0, 0));
- xbdbuf = malloc(req->oldlen, M_BPF, M_WAITOK);
+ bpfd_cnt = 0;
BPF_LOCK();
- if (req->oldlen < (bpf_bpfd_cnt * sizeof(*xbd))) {
+ CK_LIST_FOREACH(bp, &bpf_iflist, bif_next) {
+ CK_LIST_FOREACH(bd, &bp->bif_wlist, bd_next)
+ bpfd_cnt++;
+ CK_LIST_FOREACH(bd, &bp->bif_dlist, bd_next)
+ bpfd_cnt++;
+ }
+ if (bpfd_cnt == 0 || req->oldptr == NULL) {
+ BPF_UNLOCK();
+ return (SYSCTL_OUT(req, 0, bpfd_cnt * sizeof(*xbd)));
+ }
+ if (req->oldlen < bpfd_cnt * sizeof(*xbd)) {
BPF_UNLOCK();
- free(xbdbuf, M_BPF);
return (ENOMEM);
}
+ xbdbuf = malloc(bpfd_cnt * sizeof(*xbd), M_BPF, M_WAITOK);
index = 0;
CK_LIST_FOREACH(bp, &bpf_iflist, bif_next) {
/* Send writers-only first */
CK_LIST_FOREACH(bd, &bp->bif_wlist, bd_next) {
+ MPASS(index <= bpfd_cnt);
xbd = &xbdbuf[index++];
bpfstats_fill_xbpf(xbd, bd);
}
CK_LIST_FOREACH(bd, &bp->bif_dlist, bd_next) {
+ MPASS(index <= bpfd_cnt);
xbd = &xbdbuf[index++];
bpfstats_fill_xbpf(xbd, bd);
}