Date: Mon, 18 Jul 2016 09:09:57 GMT From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r306424 - soc2016/vincenzo/head/sys/dev/netmap Message-ID: <201607180909.u6I99vr5077395@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vincenzo Date: Mon Jul 18 09:09:57 2016 New Revision: 306424 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=306424 Log: freebsd: ptnet: collect interface statistics Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 18 09:09:48 2016 (r306423) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Mon Jul 18 09:09:57 2016 (r306424) @@ -103,18 +103,27 @@ struct ptnet_softc; +struct ptnet_queue_stats { + uint64_t packets; /* if_[io]packets */ + uint64_t bytes; /* if_[io]bytes */ + uint64_t errors; /* if_[io]errors */ + uint64_t iqdrops; /* if_iqdrops */ + uint64_t mcasts; /* if_[io]mcasts */ +}; + struct ptnet_queue { - struct ptnet_softc *sc; - struct resource *irq; - void *cookie; - int kring_id; - struct ptnet_ring *ptring; - unsigned int kick; - struct mtx lock; - struct buf_ring *bufring; /* for TX queues */ - struct taskqueue *taskq; - struct task task; - char lock_name[16]; + struct ptnet_softc *sc; + struct resource *irq; + void *cookie; + int kring_id; + struct ptnet_ring *ptring; + unsigned int kick; + struct mtx lock; + struct buf_ring *bufring; /* for TX queues */ + struct ptnet_queue_stats stats; + struct taskqueue *taskq; + struct task task; + char lock_name[16]; }; #define PTNET_Q_LOCK(_pq) mtx_lock(&(_pq)->lock) @@ -988,8 +997,33 @@ { struct ptnet_softc *sc = opaque; struct ifnet *ifp = sc->ifp; + struct ptnet_queue_stats stats[2]; + int i; + + /* Accumulate statistics over the queues. */ + memset(stats, 0, sizeof(stats)); + for (i = 0; i < sc->num_rings; i++) { + struct ptnet_queue *pq = sc->queues + i; + int idx = (i < sc->num_tx_rings) ? 0 : 1; + + stats[idx].packets += pq->stats.packets; + stats[idx].bytes += pq->stats.bytes; + stats[idx].errors += pq->stats.errors; + stats[idx].iqdrops += pq->stats.iqdrops; + stats[idx].mcasts += pq->stats.mcasts; + } + + /* Update interface statistics. */ + ifp->if_opackets = stats[0].packets; + ifp->if_obytes = stats[0].bytes; + ifp->if_omcasts = stats[0].mcasts; + ifp->if_oerrors = stats[0].errors; + ifp->if_ipackets = stats[1].packets; + ifp->if_ibytes = stats[1].bytes; + ifp->if_imcasts = stats[1].mcasts; + ifp->if_ierrors = stats[1].errors; + ifp->if_iqdrops = stats[1].iqdrops; - (void)ifp; callout_schedule(&sc->tick, hz); } @@ -1759,6 +1793,7 @@ * occurred while preparing the vnet * header. Let's go ahead with the next * packet. */ + pq->stats.errors ++; drbr_advance(ifp, pq->bufring); continue; } @@ -1818,6 +1853,12 @@ /* Copy the packet to listeners. */ ETHER_BPF_MTAP(ifp, mhead); + pq->stats.packets ++; + pq->stats.bytes += mhead->m_pkthdr.len; + if (mhead->m_flags & M_MCAST) { + pq->stats.mcasts ++; + } + m_freem(mhead); count ++; @@ -1876,6 +1917,7 @@ /* ENOBUFS when the bufring is full */ RD(1, "%s: drbr_enqueue() failed %d\n", __func__, err); + pq->stats.errors ++; return err; } @@ -1969,7 +2011,7 @@ struct netmap_slot *slot; unsigned int nmbuf_len; uint8_t *nmbuf; - +host_sync: if (head == ring->tail) { /* We ran out of slot, let's see if the host has * added some, by reading hwcur and hwtail from @@ -2004,8 +2046,10 @@ /* There is no good reason why host should * put the header in multiple netmap slots. * If this is the case, discard. */ + RD(1, "Fragmented vnet-hdr: dropping"); head = ptnet_rx_discard(kring, head); - continue; + pq->stats.iqdrops ++; + goto skip; } ND(1, "%s: vnet hdr: flags %x csum_start %u " "csum_ofs %u hdr_len = %u gso_size %u " @@ -2024,6 +2068,7 @@ if (unlikely(mhead == NULL)) { device_printf(sc->dev, "%s: failed to allocate mbuf " "head\n", __func__); + pq->stats.errors ++; break; } @@ -2050,6 +2095,7 @@ __func__, head, prev_head); head = prev_head; m_freem(mhead); + pq->stats.errors ++; if (may_resched) { taskqueue_enqueue(pq->taskq, &pq->task); @@ -2067,11 +2113,12 @@ if (unlikely(head == ring->tail)) { /* The very last slot prepared by the host has - * the NS_MOREFRAG set. This is an error that - * we handle by accepting the truncated packet, - * and let the network stack drop it. */ - RD(1, "Warning: Truncating incomplete packet"); - break; + * the NS_MOREFRAG set. Drop it and continue + * the outer cycle (to do the double-check). */ + RD(1, "Incomplete packet: dropping"); + m_freem(mhead); + pq->stats.iqdrops ++; + goto host_sync; } slot = ring->slot + head; @@ -2104,9 +2151,17 @@ if (have_vnet_hdr && (vh->flags & (VIRTIO_NET_HDR_F_NEEDS_CSUM | VIRTIO_NET_HDR_F_DATA_VALID))) { - ptnet_rx_csum(mhead, vh); + if (unlikely(ptnet_rx_csum(mhead, vh))) { + m_freem(mhead); + RD(1, "Csum offload error: dropping"); + pq->stats.iqdrops ++; + goto skip; + } } + pq->stats.packets ++; + pq->stats.bytes += mhead->m_pkthdr.len; + PTNET_Q_UNLOCK(pq); (*ifp->if_input)(ifp, mhead); PTNET_Q_LOCK(pq); @@ -2116,7 +2171,7 @@ * have the lock. Stop any processing and exit. */ goto unlock; } - +skip: count ++; if (++batch_count == PTNET_RX_BATCH) { /* Some packets have been pushed to the network stack.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607180909.u6I99vr5077395>
