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 = ∑
+ 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,