[dpdk-dev] [PATCH v3 12/22] net/atlantic: device statistics, xstats

Igor Russkikh igor.russkikh at aquantia.com
Sat Sep 29 12:30:26 CEST 2018


From: Pavel Belous <Pavel.Belous at aquantia.com>

Signed-off-by: Igor Russkikh <igor.russkikh at aquantia.com>
Signed-off-by: Pavel Belous <Pavel.Belous at aquantia.com>
---
 drivers/net/atlantic/atl_ethdev.c | 154 ++++++++++++++++++++++++++++++++++++++
 drivers/net/atlantic/atl_ethdev.h |   1 +
 drivers/net/atlantic/atl_rxtx.c   |  11 ++-
 drivers/net/atlantic/atl_types.h  |  41 ++++++++++
 4 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 75c9fa169925..fc1d862042d2 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -24,6 +24,24 @@ static void atl_dev_close(struct rte_eth_dev *dev);
 static int  atl_dev_reset(struct rte_eth_dev *dev);
 static int  atl_dev_link_update(struct rte_eth_dev *dev, int wait);
 
+static int atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
+				    struct rte_eth_xstat_name *xstats_names,
+				    unsigned int size);
+
+static int atl_dev_stats_get(struct rte_eth_dev *dev,
+				struct rte_eth_stats *stats);
+
+static int atl_dev_xstats_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstat *stats, unsigned int n);
+
+static void atl_dev_stats_reset(struct rte_eth_dev *dev);
+static void atl_dev_xstats_reset(struct rte_eth_dev *dev);
+
+static int atl_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
+					     uint16_t queue_id,
+					     uint8_t stat_idx,
+					     uint8_t is_rx);
+
 static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
 			      size_t fw_size);
 
@@ -113,6 +131,33 @@ static const struct rte_eth_desc_lim tx_desc_lim = {
 	.nb_mtu_seg_max = ATL_TX_MAX_SEG,
 };
 
+#define ATL_XSTATS_FIELD(name) { \
+	#name, \
+	offsetof(struct aq_stats_s, name) \
+}
+
+struct atl_xstats_tbl_s {
+	const char *name;
+	unsigned int offset;
+};
+
+static struct atl_xstats_tbl_s atl_xstats_tbl[] = {
+	ATL_XSTATS_FIELD(uprc),
+	ATL_XSTATS_FIELD(mprc),
+	ATL_XSTATS_FIELD(bprc),
+	ATL_XSTATS_FIELD(erpt),
+	ATL_XSTATS_FIELD(uptc),
+	ATL_XSTATS_FIELD(mptc),
+	ATL_XSTATS_FIELD(bptc),
+	ATL_XSTATS_FIELD(erpr),
+	ATL_XSTATS_FIELD(ubrc),
+	ATL_XSTATS_FIELD(ubtc),
+	ATL_XSTATS_FIELD(mbrc),
+	ATL_XSTATS_FIELD(mbtc),
+	ATL_XSTATS_FIELD(bbrc),
+	ATL_XSTATS_FIELD(bbtc),
+};
+
 static const struct eth_dev_ops atl_eth_dev_ops = {
 	.dev_configure	      = atl_dev_configure,
 	.dev_start	      = atl_dev_start,
@@ -125,6 +170,14 @@ static const struct eth_dev_ops atl_eth_dev_ops = {
 	/* Link */
 	.link_update	      = atl_dev_link_update,
 
+	/* Stats */
+	.stats_get	      = atl_dev_stats_get,
+	.xstats_get	      = atl_dev_xstats_get,
+	.xstats_get_names     = atl_dev_xstats_get_names,
+	.stats_reset	      = atl_dev_stats_reset,
+	.xstats_reset	      = atl_dev_xstats_reset,
+	.queue_stats_mapping_set = atl_dev_queue_stats_mapping_set,
+
 	.fw_version_get       = atl_fw_version_get,
 	.dev_infos_get	      = atl_dev_info_get,
 	.dev_supported_ptypes_get = atl_dev_supported_ptypes_get,
@@ -286,6 +339,9 @@ eth_atl_dev_init(struct rte_eth_dev *eth_dev)
 			(u8 *)&eth_dev->data->mac_addrs[0]) != 0)
 		return -EINVAL;
 
+	/* Reset the hw statistics */
+	atl_dev_stats_reset(eth_dev);
+
 	rte_intr_callback_register(intr_handle,
 				   atl_dev_interrupt_handler, eth_dev);
 
@@ -613,6 +669,104 @@ atl_dev_reset(struct rte_eth_dev *dev)
 	return ret;
 }
 
+
+static int
+atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct atl_adapter *adapter =
+		(struct atl_adapter *)dev->data->dev_private;
+	struct aq_hw_s *hw = &adapter->hw;
+	struct atl_sw_stats *swstats = &adapter->sw_stats;
+	unsigned int i;
+
+	hw->aq_fw_ops->update_stats(hw);
+
+	/* Fill out the rte_eth_stats statistics structure */
+	stats->ipackets = hw->curr_stats.dma_pkt_rc;
+	stats->ibytes = hw->curr_stats.dma_oct_rc;
+	stats->imissed = hw->curr_stats.dpc;
+	stats->ierrors = hw->curr_stats.erpt;
+
+	stats->opackets = hw->curr_stats.dma_pkt_tc;
+	stats->obytes = hw->curr_stats.dma_oct_tc;
+	stats->oerrors = 0;
+
+	stats->rx_nombuf = swstats->rx_nombuf;
+
+	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
+		stats->q_ipackets[i] = swstats->q_ipackets[i];
+		stats->q_opackets[i] = swstats->q_opackets[i];
+		stats->q_ibytes[i] = swstats->q_ibytes[i];
+		stats->q_obytes[i] = swstats->q_obytes[i];
+		stats->q_errors[i] = swstats->q_errors[i];
+	}
+	return 0;
+}
+
+static void
+atl_dev_stats_reset(struct rte_eth_dev *dev)
+{
+	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+	hw->aq_fw_ops->update_stats(hw);
+
+	/* Reset software totals */
+	memset(&hw->curr_stats, 0, sizeof(hw->curr_stats));
+}
+
+static int
+atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
+			 struct rte_eth_xstat_name *xstats_names,
+			 unsigned int size)
+{
+	unsigned int i;
+
+	if (!xstats_names)
+		return RTE_DIM(atl_xstats_tbl);
+
+	for (i = 0; i < size && i < RTE_DIM(atl_xstats_tbl); i++)
+		snprintf(xstats_names[i].name, RTE_ETH_XSTATS_NAME_SIZE, "%s",
+			atl_xstats_tbl[i].name);
+
+	return size;
+}
+
+static int
+atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
+		   unsigned int n)
+{
+	struct atl_adapter *adapter =
+		(struct atl_adapter *)dev->data->dev_private;
+	struct aq_hw_s *hw = &adapter->hw;
+	unsigned int i;
+
+	if (!stats)
+		return 0;
+
+	for (i = 0; i < n && i < RTE_DIM(atl_xstats_tbl); i++) {
+		stats[i].id = i;
+		stats[i].value = *(u64 *)((uint8_t *)&hw->curr_stats +
+					atl_xstats_tbl[i].offset);
+	}
+
+	return n;
+}
+
+static void
+atl_dev_xstats_reset(struct rte_eth_dev *dev __rte_unused)
+{
+}
+
+static int
+atl_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev __rte_unused,
+					     uint16_t queue_id __rte_unused,
+					     uint8_t stat_idx __rte_unused,
+					     uint8_t is_rx __rte_unused)
+{
+	/* The mapping is hardcoded: queue 0 -> stat 0, etc */
+	return 0;
+}
+
 static int
 atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 {
diff --git a/drivers/net/atlantic/atl_ethdev.h b/drivers/net/atlantic/atl_ethdev.h
index f75ed0fd1127..90d63797b2c6 100644
--- a/drivers/net/atlantic/atl_ethdev.h
+++ b/drivers/net/atlantic/atl_ethdev.h
@@ -32,6 +32,7 @@ struct atl_interrupt {
 struct atl_adapter {
 	struct aq_hw_s             hw;
 	struct aq_hw_cfg_s         hw_cfg;
+	struct atl_sw_stats        sw_stats;
 	struct atl_interrupt       intr;
 };
 
diff --git a/drivers/net/atlantic/atl_rxtx.c b/drivers/net/atlantic/atl_rxtx.c
index 9d82a0d74f22..94054ca5c9fa 100644
--- a/drivers/net/atlantic/atl_rxtx.c
+++ b/drivers/net/atlantic/atl_rxtx.c
@@ -843,7 +843,8 @@ atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 				   "queue_id=%u", (unsigned int)rxq->port_id,
 				   (unsigned int)rxq->queue_id);
 				dev->data->rx_mbuf_alloc_failed++;
-						goto err_stop;
+				adapter->sw_stats.rx_nombuf++;
+				goto err_stop;
 			}
 
 			nb_hold++;
@@ -926,6 +927,9 @@ atl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		 * of returned packets.
 		 */
 		rx_pkts[nb_rx++] = rx_mbuf_first;
+		adapter->sw_stats.q_ipackets[rxq->queue_id]++;
+		adapter->sw_stats.q_ibytes[rxq->queue_id] +=
+			rx_mbuf_first->pkt_len;
 
 		PMD_RX_LOG(ERR, "add mbuf segs=%d pkt_len=%d",
 			rx_mbuf_first->nb_segs,
@@ -1071,6 +1075,8 @@ static inline void
 atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
 	     struct rte_mbuf *tx_pkt)
 {
+	struct atl_adapter *adapter =
+		ATL_DEV_TO_ADAPTER(&rte_eth_devices[txq->port_id]);
 	uint32_t pay_len = 0;
 	int tail = 0;
 	struct atl_tx_entry *tx_entry;
@@ -1151,6 +1157,9 @@ atl_xmit_pkt(struct aq_hw_s *hw, struct atl_tx_queue *txq,
 	txq->tx_tail = tail;
 
 	txq->tx_free -= desc_count;
+
+	adapter->sw_stats.q_opackets[txq->queue_id]++;
+	adapter->sw_stats.q_obytes[txq->queue_id] += pay_len;
 }
 
 uint16_t
diff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h
index 5f840cc8d63d..99e920315014 100644
--- a/drivers/net/atlantic/atl_types.h
+++ b/drivers/net/atlantic/atl_types.h
@@ -147,4 +147,45 @@ struct aq_fw_ops {
 	int (*set_eeprom)(struct aq_hw_s *self, u32 *data, u32 len);
 };
 
+struct atl_sw_stats {
+	u64 crcerrs;
+	u64 errbc;
+	u64 mspdc;
+	u64 mpctotal;
+	u64 mpc[8];
+	u64 mlfc;
+	u64 mrfc;
+	u64 rlec;
+	u64 lxontxc;
+	u64 lxonrxc;
+	u64 lxofftxc;
+	u64 lxoffrxc;
+	u64 pxontxc[8];
+	u64 pxonrxc[8];
+	u64 pxofftxc[8];
+	u64 pxoffrxc[8];
+	u64 gprc;
+	u64 bprc;
+	u64 mprc;
+	u64 gptc;
+	u64 gorc;
+	u64 gotc;
+	u64 tor;
+	u64 tpr;
+	u64 tpt;
+	u64 mptc;
+	u64 bptc;
+	u64 xec;
+	u64 fccrc;
+	u64 ldpcec;
+	u64 pcrc8ec;
+
+	u64 rx_nombuf;
+	u64 q_ipackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	u64 q_opackets[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	u64 q_ibytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	u64 q_obytes[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+	u64 q_errors[RTE_ETHDEV_QUEUE_STAT_CNTRS];
+};
+
 #endif
-- 
2.7.4



More information about the dev mailing list