Add into the `rte_eth_stats` data structure 4 (64-bit) counters of XOFF/XON pause frames received and sent on a given port.
Update em, igb, and ixgbe drivers to return the value of the 4 XOFF/XON counters through the `rte_eth_stats_get` function exported by the DPDK API. Display the value of the 4 XOFF/XON counters in the `testpmd` application. Signed-off-by: Ivan Boule <ivan.boule at 6wind.com> --- app/test-pmd/config.c | 8 ++++++++ app/test-pmd/testpmd.c | 10 ++++++++++ lib/librte_ether/rte_ethdev.h | 4 ++++ lib/librte_pmd_e1000/em_ethdev.c | 6 ++++++ lib/librte_pmd_e1000/igb_ethdev.c | 6 ++++++ lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 6 ++++++ 6 files changed, 40 insertions(+) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 0b66671..0be0db8 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -167,6 +167,14 @@ nic_stats_display(portid_t port_id) } } + /* Display statistics of XON/XOFF pause frames, if any. */ + if ((stats.tx_pause_xon | stats.rx_pause_xon | + stats.tx_pause_xoff | stats.rx_pause_xoff) > 0) { + printf(" RX-XOFF: %-10"PRIu64" RX-XON: %-10"PRIu64"\n", + stats.rx_pause_xoff, stats.rx_pause_xon); + printf(" TX-XOFF: %-10"PRIu64" TX-XON: %-10"PRIu64"\n", + stats.tx_pause_xoff, stats.tx_pause_xon); + } printf(" %s############################%s\n", nic_stats_border, nic_stats_border); } diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 58833ac..69eb26c 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -674,6 +674,16 @@ fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) if (stats->rx_nombuf > 0) printf(" RX-nombufs:%14"PRIu64"\n", stats->rx_nombuf); } + + /* Display statistics of XON/XOFF pause frames, if any. */ + if ((stats->tx_pause_xon | stats->rx_pause_xon | + stats->tx_pause_xoff | stats->rx_pause_xoff) > 0) { + printf(" RX-XOFF: %-14"PRIu64" RX-XON: %-14"PRIu64"\n", + stats->rx_pause_xoff, stats->rx_pause_xon); + printf(" TX-XOFF: %-14"PRIu64" TX-XON: %-14"PRIu64"\n", + stats->tx_pause_xoff, stats->tx_pause_xon); + } + #ifdef RTE_TEST_PMD_RECORD_BURST_STATS if (port->rx_stream) pkt_burst_stats_display("RX", diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 86eb295..12ecad1 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -193,6 +193,10 @@ struct rte_eth_stats { uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */ uint64_t fdirmatch; /**< Total number of RX packets matching a filter. */ uint64_t fdirmiss; /**< Total number of RX packets not matching any filter. */ + uint64_t tx_pause_xon; /**< Total nb. of XON pause frame sent. */ + uint64_t rx_pause_xon; /**< Total nb. of XON pause frame received. */ + uint64_t tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */ + uint64_t rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */ uint64_t q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS]; /**< Total number of queue RX packets. */ uint64_t q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS]; diff --git a/lib/librte_pmd_e1000/em_ethdev.c b/lib/librte_pmd_e1000/em_ethdev.c index d0d2d79..5e00b98 100644 --- a/lib/librte_pmd_e1000/em_ethdev.c +++ b/lib/librte_pmd_e1000/em_ethdev.c @@ -801,6 +801,12 @@ eth_em_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) rte_stats->opackets = stats->gptc; rte_stats->ibytes = stats->gorc; rte_stats->obytes = stats->gotc; + + /* XON/XOFF pause frames stats registers */ + rte_stats->tx_pause_xon = stats->xontxc; + rte_stats->rx_pause_xon = stats->xonrxc; + rte_stats->tx_pause_xoff = stats->xofftxc; + rte_stats->rx_pause_xoff = stats->xoffrxc; } static void diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c index 9936583..f62426e 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -911,6 +911,12 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats) /* Tx Errors */ rte_stats->oerrors = stats->ecol + stats->latecol; + /* XON/XOFF pause frames */ + rte_stats->tx_pause_xon = stats->xontxc; + rte_stats->rx_pause_xon = stats->xonrxc; + rte_stats->tx_pause_xoff = stats->xofftxc; + rte_stats->rx_pause_xoff = stats->xoffrxc; + rte_stats->ipackets = stats->gprc; rte_stats->opackets = stats->gptc; rte_stats->ibytes = stats->gorc; diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 1f2d9da..7dab5e2 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -1425,6 +1425,12 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) stats->oerrors = 0; + /* XON/XOFF pause frames */ + stats->tx_pause_xon = hw_stats->lxontxc; + stats->rx_pause_xon = hw_stats->lxonrxc; + stats->tx_pause_xoff = hw_stats->lxofftxc; + stats->rx_pause_xoff = hw_stats->lxoffrxc; + /* Flow Director Stats registers */ hw_stats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); hw_stats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); -- 1.7.10.4