svn commit: r271799 - head/sys/dev/virtio/network

Gleb Smirnoff glebius at FreeBSD.org
Thu Sep 18 19:15:41 UTC 2014


Author: glebius
Date: Thu Sep 18 19:15:40 2014
New Revision: 271799
URL: http://svnweb.freebsd.org/changeset/base/271799

Log:
  - Provide if_get_counter() method for vtnet(4).
  - Do not accumulate statistics on every tick.
  - Accumulate statistics in vtnet_setup_stat_sysctl()
    and in vtnet_get_counter().
  
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  head/sys/dev/virtio/network/if_vtnet.c

Modified: head/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- head/sys/dev/virtio/network/if_vtnet.c	Thu Sep 18 18:46:38 2014	(r271798)
+++ head/sys/dev/virtio/network/if_vtnet.c	Thu Sep 18 19:15:40 2014	(r271799)
@@ -107,6 +107,7 @@ static int	vtnet_alloc_virtqueues(struct
 static int	vtnet_setup_interface(struct vtnet_softc *);
 static int	vtnet_change_mtu(struct vtnet_softc *, int);
 static int	vtnet_ioctl(struct ifnet *, u_long, caddr_t);
+static uint64_t	vtnet_get_counter(struct ifnet *, ift_counter);
 
 static int	vtnet_rxq_populate(struct vtnet_rxq *);
 static void	vtnet_rxq_free_mbufs(struct vtnet_rxq *);
@@ -160,11 +161,8 @@ static void	vtnet_qflush(struct ifnet *)
 #endif
 
 static int	vtnet_watchdog(struct vtnet_txq *);
-static void	vtnet_rxq_accum_stats(struct vtnet_rxq *,
-		    struct vtnet_rxq_stats *);
-static void	vtnet_txq_accum_stats(struct vtnet_txq *,
-		    struct vtnet_txq_stats *);
-static void	vtnet_accumulate_stats(struct vtnet_softc *);
+static void	vtnet_accum_stats(struct vtnet_softc *,
+		    struct vtnet_rxq_stats *, struct vtnet_txq_stats *);
 static void	vtnet_tick(void *);
 
 static void	vtnet_start_taskqueues(struct vtnet_softc *);
@@ -921,7 +919,7 @@ vtnet_setup_interface(struct vtnet_softc
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_init = vtnet_init;
 	ifp->if_ioctl = vtnet_ioctl;
-
+	ifp->if_get_counter = vtnet_get_counter;
 #ifndef VTNET_LEGACY_TX
 	ifp->if_transmit = vtnet_txq_mq_start;
 	ifp->if_qflush = vtnet_qflush;
@@ -2573,74 +2571,62 @@ vtnet_watchdog(struct vtnet_txq *txq)
 }
 
 static void
-vtnet_rxq_accum_stats(struct vtnet_rxq *rxq, struct vtnet_rxq_stats *accum)
+vtnet_accum_stats(struct vtnet_softc *sc, struct vtnet_rxq_stats *rxacc,
+    struct vtnet_txq_stats *txacc)
 {
-	struct vtnet_rxq_stats *st;
-
-	st = &rxq->vtnrx_stats;
 
-	accum->vrxs_ipackets += st->vrxs_ipackets;
-	accum->vrxs_ibytes += st->vrxs_ibytes;
-	accum->vrxs_iqdrops += st->vrxs_iqdrops;
-	accum->vrxs_csum += st->vrxs_csum;
-	accum->vrxs_csum_failed += st->vrxs_csum_failed;
-	accum->vrxs_rescheduled += st->vrxs_rescheduled;
-}
+	bzero(rxacc, sizeof(struct vtnet_rxq_stats));
+	bzero(txacc, sizeof(struct vtnet_txq_stats));
 
-static void
-vtnet_txq_accum_stats(struct vtnet_txq *txq, struct vtnet_txq_stats *accum)
-{
-	struct vtnet_txq_stats *st;
+	for (int i = 0; i < sc->vtnet_max_vq_pairs; i++) {
+		struct vtnet_rxq_stats *rxst;
+		struct vtnet_txq_stats *txst;
 
-	st = &txq->vtntx_stats;
+		rxst = &sc->vtnet_rxqs[i].vtnrx_stats;
+		rxacc->vrxs_ipackets += rxst->vrxs_ipackets;
+		rxacc->vrxs_ibytes += rxst->vrxs_ibytes;
+		rxacc->vrxs_iqdrops += rxst->vrxs_iqdrops;
+		rxacc->vrxs_csum += rxst->vrxs_csum;
+		rxacc->vrxs_csum_failed += rxst->vrxs_csum_failed;
+		rxacc->vrxs_rescheduled += rxst->vrxs_rescheduled;
 
-	accum->vtxs_opackets += st->vtxs_opackets;
-	accum->vtxs_obytes += st->vtxs_obytes;
-	accum->vtxs_csum += st->vtxs_csum;
-	accum->vtxs_tso += st->vtxs_tso;
-	accum->vtxs_rescheduled += st->vtxs_rescheduled;
+		txst = &sc->vtnet_txqs[i].vtntx_stats;
+		txacc->vtxs_opackets += txst->vtxs_opackets;
+		txacc->vtxs_obytes += txst->vtxs_obytes;
+		txacc->vtxs_csum += txst->vtxs_csum;
+		txacc->vtxs_tso += txst->vtxs_tso;
+		txacc->vtxs_rescheduled += txst->vtxs_rescheduled;
+	}
 }
 
-static void
-vtnet_accumulate_stats(struct vtnet_softc *sc)
+static uint64_t
+vtnet_get_counter(if_t ifp, ift_counter cnt)
 {
-	struct ifnet *ifp;
-	struct vtnet_statistics *st;
+	struct vtnet_softc *sc;
 	struct vtnet_rxq_stats rxaccum;
 	struct vtnet_txq_stats txaccum;
-	int i;
 
-	ifp = sc->vtnet_ifp;
-	st = &sc->vtnet_stats;
-	bzero(&rxaccum, sizeof(struct vtnet_rxq_stats));
-	bzero(&txaccum, sizeof(struct vtnet_txq_stats));
+	sc = if_getsoftc(ifp);
+	vtnet_accum_stats(sc, &rxaccum, &txaccum);
 
-	for (i = 0; i < sc->vtnet_max_vq_pairs; i++) {
-		vtnet_rxq_accum_stats(&sc->vtnet_rxqs[i], &rxaccum);
-		vtnet_txq_accum_stats(&sc->vtnet_txqs[i], &txaccum);
-	}
-
-	st->rx_csum_offloaded = rxaccum.vrxs_csum;
-	st->rx_csum_failed = rxaccum.vrxs_csum_failed;
-	st->rx_task_rescheduled = rxaccum.vrxs_rescheduled;
-	st->tx_csum_offloaded = txaccum.vtxs_csum;
-	st->tx_tso_offloaded = txaccum.vtxs_tso;
-	st->tx_task_rescheduled = txaccum.vtxs_rescheduled;
-
-	/*
-	 * With the exception of if_ierrors, these ifnet statistics are
-	 * only updated in the driver, so just set them to our accumulated
-	 * values. if_ierrors is updated in ether_input() for malformed
-	 * frames that we should have already discarded.
-	 */
-	ifp->if_ipackets = rxaccum.vrxs_ipackets;
-	ifp->if_iqdrops = rxaccum.vrxs_iqdrops;
-	ifp->if_ierrors = rxaccum.vrxs_ierrors;
-	ifp->if_opackets = txaccum.vtxs_opackets;
+	switch (cnt) {
+	case IFCOUNTER_IPACKETS:
+		return (rxaccum.vrxs_ipackets);
+	case IFCOUNTER_IQDROPS:
+		return (rxaccum.vrxs_iqdrops);
+	case IFCOUNTER_IERRORS:
+		return (rxaccum.vrxs_ierrors);
+	case IFCOUNTER_OPACKETS:
+		return (txaccum.vtxs_opackets);
 #ifndef VTNET_LEGACY_TX
-	ifp->if_obytes = txaccum.vtxs_obytes;
-	ifp->if_omcasts = txaccum.vtxs_omcasts;
+	case IFCOUNTER_OBYTES:
+		return (txaccum.vtxs_obytes);
+	case IFCOUNTER_OMCASTS:
+		return (txaccum.vtxs_omcasts);
 #endif
+	default:
+		return (if_get_counter_default(ifp, cnt));
+	}
 }
 
 static void
@@ -2655,7 +2641,6 @@ vtnet_tick(void *xsc)
 	timedout = 0;
 
 	VTNET_CORE_LOCK_ASSERT(sc);
-	vtnet_accumulate_stats(sc);
 
 	for (i = 0; i < sc->vtnet_act_vq_pairs; i++)
 		timedout |= vtnet_watchdog(&sc->vtnet_txqs[i]);
@@ -3762,8 +3747,18 @@ vtnet_setup_stat_sysctl(struct sysctl_ct
     struct sysctl_oid_list *child, struct vtnet_softc *sc)
 {
 	struct vtnet_statistics *stats;
+	struct vtnet_rxq_stats rxaccum;
+	struct vtnet_txq_stats txaccum;
+
+	vtnet_accum_stats(sc, &rxaccum, &txaccum);
 
 	stats = &sc->vtnet_stats;
+	stats->rx_csum_offloaded = rxaccum.vrxs_csum;
+	stats->rx_csum_failed = rxaccum.vrxs_csum_failed;
+	stats->rx_task_rescheduled = rxaccum.vrxs_rescheduled;
+	stats->tx_csum_offloaded = txaccum.vtxs_csum;
+	stats->tx_tso_offloaded = txaccum.vtxs_tso;
+	stats->tx_task_rescheduled = txaccum.vtxs_rescheduled;
 
 	SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, "mbuf_alloc_failed",
 	    CTLFLAG_RD, &stats->mbuf_alloc_failed,


More information about the svn-src-head mailing list