Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Add support for MP-safe network interface statistics...
details: https://anonhg.NetBSD.org/src/rev/1278a21310fa
branches: trunk
changeset: 744283:1278a21310fa
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Jan 29 03:16:28 2020 +0000
description:
Add support for MP-safe network interface statistics by maintaining them
in per-cpu storage, and collecting them for export in an if_data structure
when user-space wants them.
The new if_stat API is structured to make a gradual transition to the
new way in network drivers possible, and per-cpu stats are currently
disabled (thus there is no kernel ABI change). Once all drivers have
been converted, the old ABI will be removed, and per-cpu stats will be
enabled universally.
diffstat:
sys/net/Makefile | 6 +-
sys/net/files.net | 3 +-
sys/net/if.c | 53 +++++++++-------
sys/net/if.h | 24 +++++++-
sys/net/if_stats.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++
sys/net/if_stats.h | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 384 insertions(+), 28 deletions(-)
diffs (truncated from 568 to 300 lines):
diff -r e40c35202c34 -r 1278a21310fa sys/net/Makefile
--- a/sys/net/Makefile Wed Jan 29 03:04:55 2020 +0000
+++ b/sys/net/Makefile Wed Jan 29 03:16:28 2020 +0000
@@ -1,12 +1,12 @@
-# $NetBSD: Makefile,v 1.41 2020/01/20 18:38:18 thorpej Exp $
+# $NetBSD: Makefile,v 1.42 2020/01/29 03:16:28 thorpej Exp $
INCSDIR= /usr/include/net
INCS= bpf.h bpfjit.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \
if_bridgevar.h if_dl.h if_ether.h if_gif.h \
if_gre.h if_ieee1394.h if_ipsec.h if_llc.h if_media.h if_mpls.h \
- if_pflog.h if_ppp.h if_pppoe.h if_l2tp.h if_sppp.h if_srt.h if_stf.h \
- if_tap.h if_tun.h if_types.h if_vlanvar.h net_stats.h \
+ if_pflog.h if_ppp.h if_pppoe.h if_l2tp.h if_sppp.h if_srt.h if_stats.h \
+ if_stf.h if_tap.h if_tun.h if_types.h if_vlanvar.h net_stats.h \
netisr.h pfil.h pfkeyv2.h pfvar.h ppp-comp.h ppp_defs.h radix.h \
raw_cb.h route.h slcompress.h slip.h zlib.h
diff -r e40c35202c34 -r 1278a21310fa sys/net/files.net
--- a/sys/net/files.net Wed Jan 29 03:04:55 2020 +0000
+++ b/sys/net/files.net Wed Jan 29 03:16:28 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.net,v 1.24 2020/01/20 18:38:18 thorpej Exp $
+# $NetBSD: files.net,v 1.25 2020/01/29 03:16:28 thorpej Exp $
# XXX CLEANUP
define net
@@ -25,6 +25,7 @@
file net/if_mpls.c mpls needs-flag
file net/if_ppp.c ppp needs-flag
file net/if_srt.c srt
+file net/if_stats.c net
file net/if_stf.c stf & inet & inet6 needs-flag
file net/if_sl.c sl needs-flag
file net/if_spppsubr.c sppp
diff -r e40c35202c34 -r 1278a21310fa sys/net/if.c
--- a/sys/net/if.c Wed Jan 29 03:04:55 2020 +0000
+++ b/sys/net/if.c Wed Jan 29 03:16:28 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.468 2020/01/20 18:38:18 thorpej Exp $ */
+/* $NetBSD: if.c,v 1.469 2020/01/29 03:16:28 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.468 2020/01/20 18:38:18 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.469 2020/01/29 03:16:28 thorpej Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -733,6 +733,9 @@
psref_target_init(&ifp->if_psref, ifnet_psref_class);
ifp->if_ioctl_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
LIST_INIT(&ifp->if_multiaddrs);
+ if ((rv = if_stats_init(ifp)) != 0) {
+ goto fail;
+ }
IFNET_GLOBAL_LOCK();
if_getindex(ifp);
@@ -816,7 +819,7 @@
struct mbuf *m;
while ((m = if_percpuq_dequeue(ipq)) != NULL) {
- ifp->if_ipackets++;
+ if_statinc(ifp, if_ipackets);
bpf_mtap(ifp, m, BPF_D_IN);
ifp->_if_input(ifp, m);
@@ -1110,7 +1113,7 @@
KASSERT(ifp->if_percpuq == NULL);
KASSERT(!cpu_intr_p());
- ifp->if_ipackets++;
+ if_statinc(ifp, if_ipackets);
bpf_mtap(ifp, m, BPF_D_IN);
ifp->_if_input(ifp, m);
@@ -1521,6 +1524,7 @@
mutex_obj_free(ifp->if_ioctl_lock);
ifp->if_ioctl_lock = NULL;
mutex_obj_free(ifp->if_snd.ifq_lock);
+ if_stats_fini(ifp);
splx(s);
@@ -2959,6 +2963,22 @@
percpu_foreach(ro_percpu, if_tunnel_rtcache_free_pc, NULL);
}
+void
+if_export_if_data(ifnet_t * const ifp, struct if_data *ifi, bool zero_stats)
+{
+
+ /* Collet the volatile stats first; this zeros *ifi. */
+ if_stats_to_if_data(ifp, ifi, zero_stats);
+
+ ifi->ifi_type = ifp->if_type;
+ ifi->ifi_addrlen = ifp->if_addrlen;
+ ifi->ifi_hdrlen = ifp->if_hdrlen;
+ ifi->ifi_link_state = ifp->if_link_state;
+ ifi->ifi_mtu = ifp->if_mtu;
+ ifi->ifi_metric = ifp->if_metric;
+ ifi->ifi_baudrate = ifp->if_baudrate;
+ ifi->ifi_lastchange = ifp->if_lastchange;
+}
/* common */
int
@@ -3083,7 +3103,7 @@
case SIOCGIFDATA:
ifdr = data;
- ifdr->ifdr_data = ifp->if_data;
+ if_export_if_data(ifp, &ifdr->ifdr_data, false);
break;
case SIOCGIFINDEX:
@@ -3093,20 +3113,7 @@
case SIOCZIFDATA:
ifdr = data;
- ifdr->ifdr_data = ifp->if_data;
- /*
- * Assumes that the volatile counters that can be
- * zero'ed are at the end of if_data.
- */
- memset(&ifp->if_data.ifi_ipackets, 0, sizeof(ifp->if_data) -
- offsetof(struct if_data, ifi_ipackets));
- /*
- * The memset() clears to the bottm of if_data. In the area,
- * if_lastchange is included. Please be careful if new entry
- * will be added into if_data or rewite this.
- *
- * And also, update if_lastchnage.
- */
+ if_export_if_data(ifp, &ifdr->ifdr_data, true);
getnanotime(&ifp->if_lastchange);
break;
case SIOCSIFMTU:
@@ -3595,9 +3602,11 @@
goto out;
}
- ifp->if_obytes += pktlen;
+ net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
+ if_statadd_ref(nsr, if_obytes, pktlen);
if (mcast)
- ifp->if_omcasts++;
+ if_statinc_ref(nsr, if_omcasts);
+ IF_STAT_PUTREF(ifp);
if ((ifp->if_flags & IFF_OACTIVE) == 0)
if_start_lock(ifp);
@@ -3666,7 +3675,7 @@
} else
IFQ_ENQUEUE(&ifp->if_snd, m, error);
if (error != 0) {
- ++ifp->if_oerrors;
+ if_statinc(ifp, if_oerrors);
return error;
}
return 0;
diff -r e40c35202c34 -r 1278a21310fa sys/net/if.h
--- a/sys/net/if.h Wed Jan 29 03:04:55 2020 +0000
+++ b/sys/net/if.h Wed Jan 29 03:16:28 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.277 2019/09/19 06:07:24 knakahara Exp $ */
+/* $NetBSD: if.h,v 1.278 2020/01/29 03:16:28 thorpej Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -173,6 +173,8 @@
/*
* Structure defining statistics and other data kept regarding a network
* interface.
+ *
+ * Only used for exporting data from the interface.
*/
struct if_data {
/* generic interface information */
@@ -273,7 +275,20 @@
short if_timer; /* ?: time 'til if_slowtimo called */
unsigned short if_flags; /* i: up/down, broadcast, etc. */
short if_extflags; /* :: if_output MP-safe, etc. */
- struct if_data if_data; /* ?: statistics and other data about if */
+#ifdef __IF_STATS_PERCPU
+ u_char if_type; /* :: ethernet, tokenring, etc. */
+ u_char if_addrlen; /* :: media address length */
+ u_char if_hdrlen; /* :: media header length */
+ /* XXX audit :? fields here. */
+ int if_link_state; /* :? current link state */
+ uint64_t if_mtu; /* :? maximum transmission unit */
+ uint64_t if_metric; /* :? routing metric (external only) */
+ uint64_t if_baudrate; /* :? linespeed */
+ struct timespec if_lastchange; /* :? last operational state change */
+ percpu_t *if_stats; /* :: statistics */
+#else /* ! __IF_STATS_PERCPU */
+ struct if_data if_data; /* ?: statistics and other data */
+#endif /* __IF_STATS_PERCPU */
/*
* Procedure handles. If you add more of these, don't forget the
* corresponding NULL stub in if.c.
@@ -393,7 +408,10 @@
if_multiaddrs; /* 6: */
#endif
} ifnet_t;
+
+#include <net/if_stats.h>
+#ifndef __IF_STATS_PERCPU
#define if_mtu if_data.ifi_mtu
#define if_type if_data.ifi_type
#define if_addrlen if_data.ifi_addrlen
@@ -413,6 +431,7 @@
#define if_iqdrops if_data.ifi_iqdrops
#define if_noproto if_data.ifi_noproto
#define if_lastchange if_data.ifi_lastchange
+#endif /* __IF_STATS_PERCPU */
#define if_name(ifp) ((ifp)->if_xname)
#define IFF_UP 0x0001 /* interface is up */
@@ -1090,6 +1109,7 @@
void if_attachdomain(void);
void if_deactivate(struct ifnet *);
bool if_is_deactivated(const struct ifnet *);
+void if_export_if_data(struct ifnet *, struct if_data *, bool);
void if_purgeaddrs(struct ifnet *, int, void (*)(struct ifaddr *));
void if_detach(struct ifnet *);
void if_down(struct ifnet *);
diff -r e40c35202c34 -r 1278a21310fa sys/net/if_stats.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/if_stats.c Wed Jan 29 03:16:28 2020 +0000
@@ -0,0 +1,161 @@
+/* $NetBSD: if_stats.c,v 1.1 2020/01/29 03:16:28 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_stats.c,v 1.1 2020/01/29 03:16:28 thorpej Exp $");
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+
+#define IF_STATS_SIZE (sizeof(uint64_t) * IF_NSTATS)
+
+/*
+ * if_stats_init --
+ * Initialize statistics storage for a network interface.
+ */
+int
+if_stats_init(ifnet_t * const ifp)
+{
+#ifdef __IF_STATS_PERCPU
+ ifp->if_stats = percpu_alloc(IF_STATS_SIZE);
+ if (ifp->if_stats == NULL)
+ return ENOMEM;
+#endif /* __IF_STATS_PERCPU */
+ return 0;
+}
+
+/*
+ * if_stats_fini --
+ * Tear down statistics storage for a network interface.
+ */
+void
Home |
Main Index |
Thread Index |
Old Index