summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2015-12-11 06:41:01 +0000
committerarybchik <arybchik@FreeBSD.org>2015-12-11 06:41:01 +0000
commit3577b6d5dd294bce59f9e7f1f7cecd7919e4f367 (patch)
treeedf7d717a79dbd53a37502ee9b9e52e5da6f0ca8 /sys/dev
parent65747233a88907179a981731283a046e43ff4033 (diff)
downloadFreeBSD-src-3577b6d5dd294bce59f9e7f1f7cecd7919e4f367.zip
FreeBSD-src-3577b6d5dd294bce59f9e7f1f7cecd7919e4f367.tar.gz
sfxge: implement interface statistics shown by netstat
PR: 202907 Submitted by: Boris Misenov <Boris.Misenov at oktetlabs.ru> Reviewed by: gnn, philip Sponsored by: Solarflare Communications, Inc. Differential Revision: https://reviews.freebsd.org/D4317
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sfxge/sfxge.c31
-rw-r--r--sys/dev/sfxge/sfxge.h5
-rw-r--r--sys/dev/sfxge/sfxge_port.c35
-rw-r--r--sys/dev/sfxge/sfxge_tx.c29
-rw-r--r--sys/dev/sfxge/sfxge_tx.h1
-rw-r--r--sys/dev/sfxge/sfxge_version.h2
6 files changed, 100 insertions, 3 deletions
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index 46b138f..f78d175 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -69,10 +69,10 @@ __FBSDID("$FreeBSD$");
IFCAP_RXCSUM_IPV6 | IFCAP_TXCSUM_IPV6 | \
IFCAP_TSO4 | IFCAP_TSO6 | \
IFCAP_JUMBO_MTU | \
- IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
+ IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWSTATS)
#define SFXGE_CAP_ENABLE SFXGE_CAP
#define SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | \
- IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
+ IFCAP_JUMBO_MTU | IFCAP_LINKSTATE | IFCAP_HWSTATS)
MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
@@ -94,6 +94,14 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
&sfxge_tx_ring_entries, 0,
"Maximum number of descriptors in a transmit ring");
+#define SFXGE_PARAM_STATS_UPDATE_PERIOD SFXGE_PARAM(stats_update_period)
+static int sfxge_stats_update_period = SFXGE_CALLOUT_TICKS;
+TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD,
+ &sfxge_stats_update_period);
+SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period, CTLFLAG_RDTUN,
+ &sfxge_stats_update_period, 0,
+ "netstat interface statistics update period in ticks");
+
static void
sfxge_reset(void *arg, int npending);
@@ -506,10 +514,24 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
}
static void
+sfxge_tick(void *arg)
+{
+ struct sfxge_softc *sc = arg;
+
+ sfxge_port_update_stats(sc);
+ sfxge_tx_update_stats(sc);
+
+ callout_reset(&sc->tick_callout, sfxge_stats_update_period,
+ sfxge_tick, sc);
+}
+
+static void
sfxge_ifnet_fini(struct ifnet *ifp)
{
struct sfxge_softc *sc = ifp->if_softc;
+ callout_drain(&sc->tick_callout);
+
SFXGE_ADAPTER_LOCK(sc);
sfxge_stop(sc);
SFXGE_ADAPTER_UNLOCK(sc);
@@ -555,10 +577,15 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
ifp->if_transmit = sfxge_if_transmit;
ifp->if_qflush = sfxge_if_qflush;
+ callout_init(&sc->tick_callout, B_TRUE);
+
DBGPRINT(sc->dev, "ifmedia_init");
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;
+ callout_reset(&sc->tick_callout, sfxge_stats_update_period,
+ sfxge_tick, sc);
+
return (0);
fail:
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index aa1830d..cfaf06d 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -121,6 +121,8 @@ enum sfxge_evq_state {
#define SFXGE_EV_BATCH 16384
+#define SFXGE_CALLOUT_TICKS 100
+
struct sfxge_evq {
/* Structure members below are sorted by usage order */
struct sfxge_softc *sc;
@@ -274,6 +276,8 @@ struct sfxge_softc {
size_t rx_buffer_align;
uma_zone_t rx_buffer_zone;
+ struct callout tick_callout;
+
unsigned int evq_max;
unsigned int evq_count;
unsigned int rxq_count;
@@ -349,6 +353,7 @@ extern void sfxge_mac_link_update(struct sfxge_softc *sc,
efx_link_mode_t mode);
extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
+extern void sfxge_port_update_stats(struct sfxge_softc *sc);
#define SFXGE_MAX_MTU (9 * 1024)
diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c
index 420aaad..277752a 100644
--- a/sys/dev/sfxge/sfxge_port.c
+++ b/sys/dev/sfxge/sfxge_port.c
@@ -87,6 +87,41 @@ out:
return (rc);
}
+void
+sfxge_port_update_stats(struct sfxge_softc *sc)
+{
+ struct ifnet *ifp;
+ uint64_t *mac_stats;
+
+ SFXGE_PORT_LOCK(&sc->port);
+
+ /* Ignore error and use old values */
+ (void)sfxge_mac_stat_update(sc);
+
+ ifp = sc->ifnet;
+ mac_stats = (uint64_t *)sc->port.mac_stats.decode_buf;
+
+ ifp->if_ipackets = mac_stats[EFX_MAC_RX_PKTS];
+ ifp->if_ierrors = mac_stats[EFX_MAC_RX_ERRORS];
+ ifp->if_opackets = mac_stats[EFX_MAC_TX_PKTS];
+ ifp->if_oerrors = mac_stats[EFX_MAC_TX_ERRORS];
+ ifp->if_collisions =
+ mac_stats[EFX_MAC_TX_SGL_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_MULT_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_EX_COL_PKTS] +
+ mac_stats[EFX_MAC_TX_LATE_COL_PKTS];
+ ifp->if_ibytes = mac_stats[EFX_MAC_RX_OCTETS];
+ ifp->if_obytes = mac_stats[EFX_MAC_TX_OCTETS];
+ /* if_imcasts is maintained in net/if_ethersubr.c */
+ ifp->if_omcasts =
+ mac_stats[EFX_MAC_TX_MULTICST_PKTS] +
+ mac_stats[EFX_MAC_TX_BRDCST_PKTS];
+ /* if_iqdrops is maintained in net/if_ethersubr.c */
+ /* if_noproto is maintained in net/if_ethersubr.c */
+
+ SFXGE_PORT_UNLOCK(&sc->port);
+}
+
static int
sfxge_mac_stat_handler(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 9579975..398272d 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -1683,6 +1683,35 @@ sfxge_tx_stat_init(struct sfxge_softc *sc)
}
}
+static uint64_t
+sfxge_tx_get_drops(struct sfxge_softc *sc)
+{
+ unsigned int index;
+ uint64_t drops = 0;
+ struct sfxge_txq *txq;
+
+ /* Sum across all TX queues */
+ for (index = 0; index < sc->txq_count; index++) {
+ txq = sc->txq[index];
+ /*
+ * In theory, txq->put_overflow and txq->netdown_drops
+ * should use atomic operation and other should be
+ * obtained under txq lock, but it is just statistics.
+ */
+ drops += txq->drops + txq->get_overflow +
+ txq->get_non_tcp_overflow +
+ txq->put_overflow + txq->netdown_drops +
+ txq->tso_pdrop_too_many + txq->tso_pdrop_no_rsrc;
+ }
+ return (drops);
+}
+
+void
+sfxge_tx_update_stats(struct sfxge_softc *sc)
+{
+ sc->ifnet->if_oerrors += sfxge_tx_get_drops(sc);
+}
+
void
sfxge_tx_fini(struct sfxge_softc *sc)
{
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index 67bedc2..9d411ea 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -220,6 +220,7 @@ struct sfxge_txq {
struct sfxge_evq;
+extern void sfxge_tx_update_stats(struct sfxge_softc *sc);
extern int sfxge_tx_init(struct sfxge_softc *sc);
extern void sfxge_tx_fini(struct sfxge_softc *sc);
diff --git a/sys/dev/sfxge/sfxge_version.h b/sys/dev/sfxge/sfxge_version.h
index f5f4882..9d93e79 100644
--- a/sys/dev/sfxge/sfxge_version.h
+++ b/sys/dev/sfxge/sfxge_version.h
@@ -36,6 +36,6 @@
#ifndef _SFXGE_VERSION_H
#define _SFXGE_VERSION_H
-#define SFXGE_VERSION_STRING "v4.5.2.1000"
+#define SFXGE_VERSION_STRING "v4.5.3.1002"
#endif /* _SFXGE_DRIVER_VERSION_H */
OpenPOWER on IntegriCloud