Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Dec 2025 23:20:01 +0000
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 845896655815 - main - bpf: calculate net.bpf.stats buffer size dynamically
Message-ID:  <6930c5a1.3d56a.1c37f13b@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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);
 		}


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6930c5a1.3d56a.1c37f13b>