Module Name:    src
Committed By:   ozaki-r
Date:           Wed Feb  1 08:15:15 UTC 2017

Modified Files:
        src/sys/net: bpf.c

Log Message:
Make bpf_gstats percpu


To generate a diff of this commit:
cvs rdiff -u -r1.209 -r1.210 src/sys/net/bpf.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/bpf.c
diff -u src/sys/net/bpf.c:1.209 src/sys/net/bpf.c:1.210
--- src/sys/net/bpf.c:1.209	Wed Feb  1 08:13:45 2017
+++ src/sys/net/bpf.c	Wed Feb  1 08:15:15 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: bpf.c,v 1.209 2017/02/01 08:13:45 ozaki-r Exp $	*/
+/*	$NetBSD: bpf.c,v 1.210 2017/02/01 08:15:15 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.209 2017/02/01 08:13:45 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.210 2017/02/01 08:15:15 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.20
 #include <sys/sysctl.h>
 #include <sys/kauth.h>
 #include <sys/syslog.h>
+#include <sys/percpu.h>
 
 #include <net/if.h>
 #include <net/slip.h>
@@ -120,7 +121,15 @@ struct bpfjit_ops bpfjit_module_ops = {
 /*
  * Global BPF statistics returned by net.bpf.stats sysctl.
  */
-static struct bpf_stat	bpf_gstats;
+static struct percpu	*bpf_gstats_percpu; /* struct bpf_stat */
+
+#define BPF_STATINC(id)					\
+	{						\
+		struct bpf_stat *__stats =		\
+		    percpu_getref(bpf_gstats_percpu);	\
+		__stats->bs_##id++;			\
+		percpu_putref(bpf_gstats_percpu);	\
+	}
 
 /*
  * Use a mutex to avoid a race condition between gathering the stats/peers
@@ -466,9 +475,7 @@ bpf_init(void)
 	PSLIST_INIT(&bpf_iflist);
 	PSLIST_INIT(&bpf_dlist);
 
-	bpf_gstats.bs_recv = 0;
-	bpf_gstats.bs_drop = 0;
-	bpf_gstats.bs_capt = 0;
+	bpf_gstats_percpu = percpu_alloc(sizeof(struct bpf_stat));
 
 	return;
 }
@@ -1496,7 +1503,7 @@ bpf_deliver(struct bpf_if *bp, void *(*c
 			continue;
 		}
 		d->bd_rcount++;
-		bpf_gstats.bs_recv++;
+		BPF_STATINC(recv);
 
 		if (d->bd_jitcode)
 			slen = d->bd_jitcode(NULL, &args);
@@ -1787,7 +1794,7 @@ catchpacket(struct bpf_d *d, u_char *pkt
 	int do_wakeup = 0;
 
 	++d->bd_ccount;
-	++bpf_gstats.bs_capt;
+	BPF_STATINC(capt);
 	/*
 	 * Figure out how many bytes to move.  If the packet is
 	 * greater or equal to the snapshot length, transfer that
@@ -1826,7 +1833,7 @@ catchpacket(struct bpf_d *d, u_char *pkt
 			 * so drop the packet.
 			 */
 			++d->bd_dcount;
-			++bpf_gstats.bs_drop;
+			BPF_STATINC(drop);
 			return;
 		}
 		ROTATE_BUFFERS(d);
@@ -2244,6 +2251,38 @@ sysctl_net_bpf_peers(SYSCTLFN_ARGS)
 	return (error);
 }
 
+static void
+bpf_stats(void *p, void *arg, struct cpu_info *ci __unused)
+{
+	struct bpf_stat *const stats = p;
+	struct bpf_stat *sum = arg;
+
+	sum->bs_recv += stats->bs_recv;
+	sum->bs_drop += stats->bs_drop;
+	sum->bs_capt += stats->bs_capt;
+}
+
+static int
+bpf_sysctl_gstats_handler(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node;
+	int error;
+	struct bpf_stat sum;
+
+	memset(&sum, 0, sizeof(sum));
+	node = *rnode;
+
+	percpu_foreach(bpf_gstats_percpu, bpf_stats, &sum);
+
+	node.sysctl_data = &sum;
+	node.sysctl_size = sizeof(sum);
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error != 0 || newp == NULL)
+		return error;
+
+	return 0;
+}
+
 static struct sysctllog *bpf_sysctllog;
 static void
 sysctl_net_bpf_setup(void)
@@ -2276,7 +2315,7 @@ sysctl_net_bpf_setup(void)
 			CTLFLAG_PERMANENT,
 			CTLTYPE_STRUCT, "stats",
 			SYSCTL_DESCR("BPF stats"),
-			NULL, 0, &bpf_gstats, sizeof(bpf_gstats),
+			bpf_sysctl_gstats_handler, 0, NULL, 0,
 			CTL_NET, node->sysctl_num, CTL_CREATE, CTL_EOL);
 		sysctl_createv(&bpf_sysctllog, 0, NULL, NULL,
 			CTLFLAG_PERMANENT,

Reply via email to