diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2017-01-20 08:10:55 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2017-01-20 08:10:55 +0000 |
commit | 5b09ffb4c43485a30a70255ce08146b8a0fdb11c (patch) | |
tree | 5f01717a7d6eb731d95a6299a35dc4f5d10ab88e /sys | |
parent | 8f28d7e250f97bf1648be604a9fc9da18dcd1853 (diff) |
use per-cpu counters for rtstat.
ok mpi@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/route.c | 20 | ||||
-rw-r--r-- | sys/net/route.h | 22 | ||||
-rw-r--r-- | sys/net/rtsock.c | 26 |
3 files changed, 54 insertions, 14 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index 66df750353a..3448bc360ba 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.346 2017/01/19 04:06:26 phessler Exp $ */ +/* $OpenBSD: route.c,v 1.347 2017/01/20 08:10:54 dlg Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -150,7 +150,7 @@ static uint32_t rt_hashjitter; extern unsigned int rtmap_limit; -struct rtstat rtstat; +struct cpumem * rtcounters; int rttrash; /* routes not in table but not freed */ int ifatrash; /* ifas not in ifp list but not free */ @@ -191,6 +191,8 @@ TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels); void route_init(void) { + rtcounters = counters_alloc(rts_ncounters, M_COUNTERS); + pool_init(&rtentry_pool, sizeof(struct rtentry), 0, IPL_SOFTNET, 0, "rtentry", NULL); @@ -273,7 +275,7 @@ rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid) } rt->rt_use++; } else - rtstat.rts_unreach++; + rtstat_inc(rts_unreach); return (rt); } @@ -545,7 +547,7 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway, { struct rtentry *rt; int error = 0; - u_int32_t *stat = NULL; + enum rtstat_counters stat = rts_ncounters; struct rt_addrinfo info; struct ifaddr *ifa; unsigned int ifidx = 0; @@ -617,7 +619,7 @@ create: flags = rt->rt_flags; prio = rt->rt_priority; } - stat = &rtstat.rts_dynamic; + stat = rts_dynamic; } else { /* * Smash the current notion of the gateway to @@ -626,7 +628,7 @@ create: rt->rt_flags |= RTF_MODIFIED; flags |= RTF_MODIFIED; prio = rt->rt_priority; - stat = &rtstat.rts_newgateway; + stat = rts_newgateway; rt_setgate(rt, gateway, rdomain); } } else @@ -640,9 +642,9 @@ done: } out: if (error) - rtstat.rts_badredirect++; - else if (stat != NULL) - (*stat)++; + rtstat_inc(rts_badredirect); + else if (stat != rts_ncounters) + rtstat_inc(stat); bzero((caddr_t)&info, sizeof(info)); info.rti_info[RTAX_DST] = dst; info.rti_info[RTAX_GATEWAY] = gateway; diff --git a/sys/net/route.h b/sys/net/route.h index 660a91e465a..c64863dc08e 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.151 2017/01/19 23:18:29 phessler Exp $ */ +/* $OpenBSD: route.h,v 1.152 2017/01/20 08:10:54 dlg Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -319,6 +319,26 @@ struct rt_addrinfo { #ifdef _KERNEL +#include <sys/percpu.h> + +enum rtstat_counters { + rts_badredirect, /* bogus redirect calls */ + rts_dynamic, /* routes created by redirects */ + rts_newgateway, /* routes modified by redirects */ + rts_unreach, /* lookups which failed */ + rts_wildcard, /* lookups satisfied by a wildcard */ + + rts_ncounters +}; + +static inline void +rtstat_inc(enum rtstat_counters c) +{ + extern struct cpumem *rtcounters; + + counters_inc(rtcounters, c); +} + /* * This structure, and the prototypes for the rt_timer_{init,remove_all, * add,timer} functions all used with the kind permission of BSDI. diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 7e6c0132bea..5abd9a015c0 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.213 2017/01/19 23:18:29 phessler Exp $ */ +/* $OpenBSD: rtsock.c,v 1.214 2017/01/20 08:10:54 dlg Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -111,6 +111,7 @@ void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *); int sysctl_iflist(int, struct walkarg *); int sysctl_ifnames(struct walkarg *); +int sysctl_rtable_rtstat(void *, size_t *, void *); struct routecb { struct rawcb rcb; @@ -1611,9 +1612,7 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, break; case NET_RT_STATS: - error = sysctl_rdstruct(where, given, new, - &rtstat, sizeof(rtstat)); - return (error); + return (sysctl_rtable_rtstat(where, given, new)); case NET_RT_TABLE: tableid = w.w_arg; if (!rtable_exists(tableid)) @@ -1639,6 +1638,25 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new, return (error); } +int +sysctl_rtable_rtstat(void *oldp, size_t *oldlenp, void *newp) +{ + extern struct cpumem *rtcounters; + uint64_t counters[rts_ncounters]; + struct rtstat rtstat; + uint32_t *words = (uint32_t *)&rtstat; + int i; + + KASSERT(sizeof(rtstat) == (nitems(counters) * sizeof(uint32_t))); + + counters_read(rtcounters, counters, nitems(counters)); + + for (i = 0; i < nitems(counters); i++) + words[i] = (uint32_t)counters[i]; + + return (sysctl_rdstruct(oldp, oldlenp, newp, &rtstat, sizeof(rtstat))); +} + /* * Definitions of protocols supported in the ROUTE domain. */ |