From 7634c5f9156922f2929a0c310f0ae3b4f74bf177 Mon Sep 17 00:00:00 2001 From: Rasesh Mody Date: Tue, 18 Oct 2016 21:11:43 -0700 Subject: [PATCH] net/qede: add queue statistics This patch adds support for pulling per queue statistics. Signed-off-by: Rasesh Mody --- drivers/net/qede/qede_ethdev.c | 98 ++++++++++++++++++++++++++++++---- drivers/net/qede/qede_ethdev.h | 3 ++ drivers/net/qede/qede_rxtx.c | 23 ++++---- drivers/net/qede/qede_rxtx.h | 4 +- 4 files changed, 107 insertions(+), 21 deletions(-) diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 394f89a217..b91b4780dc 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -160,6 +160,15 @@ static const struct rte_qede_xstats_name_off qede_xstats_strings[] = { offsetof(struct ecore_eth_stats, tpa_coalesced_bytes)}, }; +static const struct rte_qede_xstats_name_off qede_rxq_xstats_strings[] = { + {"rx_q_segments", + offsetof(struct qede_rx_queue, rx_segs)}, + {"rx_q_hw_errors", + offsetof(struct qede_rx_queue, rx_hw_errors)}, + {"rx_q_allocation_errors", + offsetof(struct qede_rx_queue, rx_alloc_errors)} +}; + static void qede_interrupt_action(struct ecore_hwfn *p_hwfn) { ecore_int_sp_dpc((osal_int_ptr_t)(p_hwfn)); @@ -828,6 +837,8 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats) struct qede_dev *qdev = eth_dev->data->dev_private; struct ecore_dev *edev = &qdev->edev; struct ecore_eth_stats stats; + unsigned int i = 0, j = 0, qid; + struct qede_tx_queue *txq; qdev->ops->get_vport_stats(edev, &stats); @@ -858,20 +869,73 @@ qede_get_stats(struct rte_eth_dev *eth_dev, struct rte_eth_stats *eth_stats) stats.tx_mcast_bytes + stats.tx_bcast_bytes; eth_stats->oerrors = stats.tx_err_drop_pkts; + + /* Queue stats */ + for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) { + if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) { + eth_stats->q_ipackets[i] = + *(uint64_t *)( + ((char *)(qdev->fp_array[(qid)].rxq)) + + offsetof(struct qede_rx_queue, + rcv_pkts)); + eth_stats->q_errors[i] = + *(uint64_t *)( + ((char *)(qdev->fp_array[(qid)].rxq)) + + offsetof(struct qede_rx_queue, + rx_hw_errors)) + + *(uint64_t *)( + ((char *)(qdev->fp_array[(qid)].rxq)) + + offsetof(struct qede_rx_queue, + rx_alloc_errors)); + i++; + } + + if (qdev->fp_array[qid].type & QEDE_FASTPATH_TX) { + txq = qdev->fp_array[(qid)].txqs[0]; + eth_stats->q_opackets[j] = + *((uint64_t *)(uintptr_t) + (((uint64_t)(uintptr_t)(txq)) + + offsetof(struct qede_tx_queue, + xmit_pkts))); + j++; + } + } +} + +static unsigned +qede_get_xstats_count(struct qede_dev *qdev) { + return RTE_DIM(qede_xstats_strings) + + (RTE_DIM(qede_rxq_xstats_strings) * QEDE_RSS_COUNT(qdev)); } static int qede_get_xstats_names(__rte_unused struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit) { - unsigned int i, stat_cnt = RTE_DIM(qede_xstats_strings); + struct qede_dev *qdev = dev->data->dev_private; + const unsigned int stat_cnt = qede_get_xstats_count(qdev); + unsigned int i, qid, stat_idx = 0; - if (xstats_names != NULL) - for (i = 0; i < stat_cnt; i++) - snprintf(xstats_names[i].name, - sizeof(xstats_names[i].name), + if (xstats_names != NULL) { + for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { + snprintf(xstats_names[stat_idx].name, + sizeof(xstats_names[stat_idx].name), "%s", qede_xstats_strings[i].name); + stat_idx++; + } + + for (qid = 0; qid < QEDE_RSS_COUNT(qdev); qid++) { + for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { + snprintf(xstats_names[stat_idx].name, + sizeof(xstats_names[stat_idx].name), + "%.4s%d%s", + qede_rxq_xstats_strings[i].name, qid, + qede_rxq_xstats_strings[i].name + 4); + stat_idx++; + } + } + } return stat_cnt; } @@ -883,18 +947,32 @@ qede_get_xstats(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, struct qede_dev *qdev = dev->data->dev_private; struct ecore_dev *edev = &qdev->edev; struct ecore_eth_stats stats; - unsigned int num = RTE_DIM(qede_xstats_strings); + const unsigned int num = qede_get_xstats_count(qdev); + unsigned int i, qid, stat_idx = 0; if (n < num) return num; qdev->ops->get_vport_stats(edev, &stats); - for (num = 0; num < n; num++) - xstats[num].value = *(u64 *)(((char *)&stats) + - qede_xstats_strings[num].offset); + for (i = 0; i < RTE_DIM(qede_xstats_strings); i++) { + xstats[stat_idx].value = *(uint64_t *)(((char *)&stats) + + qede_xstats_strings[i].offset); + stat_idx++; + } + + for (qid = 0; qid < QEDE_QUEUE_CNT(qdev); qid++) { + if (qdev->fp_array[qid].type & QEDE_FASTPATH_RX) { + for (i = 0; i < RTE_DIM(qede_rxq_xstats_strings); i++) { + xstats[stat_idx].value = *(uint64_t *)( + ((char *)(qdev->fp_array[(qid)].rxq)) + + qede_rxq_xstats_strings[i].offset); + stat_idx++; + } + } + } - return num; + return stat_idx; } static void diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h index 7b235b1543..5ab36a5bba 100644 --- a/drivers/net/qede/qede_ethdev.h +++ b/drivers/net/qede/qede_ethdev.h @@ -69,6 +69,9 @@ #define QEDE_TSS_COUNT(qdev) (((qdev)->num_queues - (qdev)->fp_num_rx) * \ (qdev)->num_tc) +#define QEDE_FASTPATH_TX (1 << 0) +#define QEDE_FASTPATH_RX (1 << 1) + #define QEDE_DUPLEX_FULL 1 #define QEDE_DUPLEX_HALF 2 #define QEDE_DUPLEX_UNKNOWN 0xff diff --git a/drivers/net/qede/qede_rxtx.c b/drivers/net/qede/qede_rxtx.c index bfcb16c580..2e181c8ca7 100644 --- a/drivers/net/qede/qede_rxtx.c +++ b/drivers/net/qede/qede_rxtx.c @@ -10,9 +10,6 @@ static bool gro_disable = 1; /* mod_param */ -#define QEDE_FASTPATH_TX (1 << 0) -#define QEDE_FASTPATH_RX (1 << 1) - static inline int qede_alloc_rx_buffer(struct qede_rx_queue *rxq) { struct rte_mbuf *new_mb = NULL; @@ -838,7 +835,7 @@ static inline uint32_t qede_rx_cqe_to_pkt_type(uint16_t flags) } int qede_process_sg_pkts(void *p_rxq, struct rte_mbuf *rx_mb, - int num_frags, uint16_t pkt_len) + int num_segs, uint16_t pkt_len) { struct qede_rx_queue *rxq = p_rxq; struct qede_dev *qdev = rxq->qdev; @@ -849,13 +846,13 @@ int qede_process_sg_pkts(void *p_rxq, struct rte_mbuf *rx_mb, register struct rte_mbuf *seg2 = NULL; seg1 = rx_mb; - while (num_frags) { + while (num_segs) { cur_size = pkt_len > rxq->rx_buf_size ? rxq->rx_buf_size : pkt_len; if (!cur_size) { PMD_RX_LOG(DEBUG, rxq, "SG packet, len and num BD mismatch\n"); - qede_recycle_rx_bd_ring(rxq, qdev, num_frags); + qede_recycle_rx_bd_ring(rxq, qdev, num_segs); return -EINVAL; } @@ -876,7 +873,8 @@ int qede_process_sg_pkts(void *p_rxq, struct rte_mbuf *rx_mb, seg2->data_len = cur_size; seg1->next = seg2; seg1 = seg1->next; - num_frags--; + num_segs--; + rxq->rx_segs++; continue; } seg1 = NULL; @@ -904,7 +902,7 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) register struct rte_mbuf *seg1 = NULL; enum eth_rx_cqe_type cqe_type; uint16_t len, pad, preload_idx, pkt_len, parse_flag; - uint8_t csum_flag, num_frags; + uint8_t csum_flag, num_segs; enum rss_hash_type htype; int ret; @@ -978,11 +976,13 @@ qede_recv_pkts(void *p_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) if (fp_cqe->bd_num > 1) { pkt_len = rte_le_to_cpu_16(fp_cqe->pkt_len); - num_frags = fp_cqe->bd_num - 1; + num_segs = fp_cqe->bd_num - 1; + + rxq->rx_segs++; pkt_len -= len; seg1 = rx_mb; - ret = qede_process_sg_pkts(p_rxq, seg1, num_frags, + ret = qede_process_sg_pkts(p_rxq, seg1, num_segs, pkt_len); if (ret != ECORE_SUCCESS) { qede_recycle_rx_bd_ring(rxq, qdev, @@ -1045,6 +1045,8 @@ next_cqe: qede_update_rx_prod(qdev, rxq); + rxq->rcv_pkts += rx_pkt; + PMD_RX_LOG(DEBUG, rxq, "rx_pkts=%u core=%d\n", rx_pkt, rte_lcore_id()); return rx_pkt; @@ -1237,6 +1239,7 @@ qede_xmit_pkts(void *p_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) bd_prod = rte_cpu_to_le_16(ecore_chain_get_prod_idx(&txq->tx_pbl)); nb_pkt_sent++; + txq->xmit_pkts++; } /* Write value of prod idx into bd_prod */ diff --git a/drivers/net/qede/qede_rxtx.h b/drivers/net/qede/qede_rxtx.h index da47b21bb4..ed9a529b08 100644 --- a/drivers/net/qede/qede_rxtx.h +++ b/drivers/net/qede/qede_rxtx.h @@ -99,6 +99,8 @@ struct qede_rx_queue { uint16_t queue_id; uint16_t port_id; uint16_t rx_buf_size; + uint64_t rcv_pkts; + uint64_t rx_segs; uint64_t rx_hw_errors; uint64_t rx_alloc_errors; struct qede_dev *qdev; @@ -130,7 +132,7 @@ struct qede_tx_queue { void OSAL_IOMEM *doorbell_addr; volatile union db_prod tx_db; uint16_t port_id; - uint64_t txq_counter; + uint64_t xmit_pkts; struct qede_dev *qdev; }; -- 2.20.1