| From 30a3d6e23880094edfc51b49b11099c8b8bfa8cd Mon Sep 17 00:00:00 2001 |
| From: John Lo <loj@cisco.com> |
| Date: Tue, 7 Jun 2016 12:36:23 +0200 |
| Subject: [PATCH 15/17] ENIC counter improvement |
| |
| --- |
| drivers/net/enic/enic.h | 7 +++++++ |
| drivers/net/enic/enic_main.c | 38 ++++++++++++++++++++++++++++++++++---- |
| drivers/net/enic/enic_rxtx.c | 15 +++++++-------- |
| 3 files changed, 48 insertions(+), 12 deletions(-) |
| |
| diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h |
| index 43b82a6..7c1b5c9 100644 |
| --- a/drivers/net/enic/enic.h |
| +++ b/drivers/net/enic/enic.h |
| @@ -91,6 +91,11 @@ struct enic_fdir { |
| struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX]; |
| }; |
| |
| +struct enic_soft_stats { |
| + rte_atomic64_t rx_nombuf; |
| + rte_atomic64_t rx_packet_errors; |
| +}; |
| + |
| /* Per-instance private data structure */ |
| struct enic { |
| struct enic *next; |
| @@ -133,6 +138,8 @@ struct enic { |
| /* interrupt resource */ |
| struct vnic_intr intr; |
| unsigned int intr_count; |
| + |
| + struct enic_soft_stats soft_stats; |
| }; |
| |
| static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq) |
| diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c |
| index 9bfdec1..a00565a 100644 |
| --- a/drivers/net/enic/enic_main.c |
| +++ b/drivers/net/enic/enic_main.c |
| @@ -142,22 +142,51 @@ static void enic_log_q_error(struct enic *enic) |
| } |
| |
| |
| +static void enic_clear_soft_stats(struct enic *enic) |
| +{ |
| + struct enic_soft_stats *soft_stats = &enic->soft_stats; |
| + rte_atomic64_clear(&soft_stats->rx_nombuf); |
| + rte_atomic64_clear(&soft_stats->rx_packet_errors); |
| +} |
| + |
| +static void enic_init_soft_stats(struct enic *enic) |
| +{ |
| + struct enic_soft_stats *soft_stats = &enic->soft_stats; |
| + rte_atomic64_init(&soft_stats->rx_nombuf); |
| + rte_atomic64_init(&soft_stats->rx_packet_errors); |
| + enic_clear_soft_stats(enic); |
| +} |
| + |
| void enic_dev_stats_clear(struct enic *enic) |
| { |
| if (vnic_dev_stats_clear(enic->vdev)) |
| dev_err(enic, "Error in clearing stats\n"); |
| + enic_clear_soft_stats(enic); |
| } |
| |
| void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats) |
| { |
| struct vnic_stats *stats; |
| + struct enic_soft_stats *soft_stats = &enic->soft_stats; |
| + int64_t rx_truncated; |
| + uint64_t rx_packet_errors; |
| |
| if (vnic_dev_stats_dump(enic->vdev, &stats)) { |
| dev_err(enic, "Error in getting stats\n"); |
| return; |
| } |
| |
| - r_stats->ipackets = stats->rx.rx_frames_ok; |
| + /* The number of truncated packets can only be calculated by |
| + * subtracting a hardware counter from error packets received by |
| + * the driver. Note: this causes transient inaccuracies in the |
| + * ipackets count. Also, the length of truncated packets are |
| + * counted in ibytes even though truncated packets are dropped |
| + * which can make ibytes be slightly higher than it should be. |
| + */ |
| + rx_packet_errors = rte_atomic64_read(&soft_stats->rx_packet_errors); |
| + rx_truncated = rx_packet_errors - stats->rx.rx_errors; |
| + |
| + r_stats->ipackets = stats->rx.rx_frames_ok - rx_truncated; |
| r_stats->opackets = stats->tx.tx_frames_ok; |
| |
| r_stats->ibytes = stats->rx.rx_bytes_ok; |
| @@ -166,10 +195,9 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats) |
| r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop; |
| r_stats->oerrors = stats->tx.tx_errors; |
| |
| - r_stats->imissed = stats->rx.rx_no_bufs; |
| + r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated; |
| |
| - r_stats->imcasts = stats->rx.rx_multicast_frames_ok; |
| - r_stats->rx_nombuf = stats->rx.rx_no_bufs; |
| + r_stats->rx_nombuf = rte_atomic64_read(&soft_stats->rx_nombuf); |
| } |
| |
| void enic_del_mac_address(struct enic *enic) |
| @@ -755,6 +783,8 @@ int enic_setup_finish(struct enic *enic) |
| { |
| int ret; |
| |
| + enic_init_soft_stats(enic); |
| + |
| ret = enic_set_rss_nic_cfg(enic); |
| if (ret) { |
| dev_err(enic, "Failed to config nic, aborting.\n"); |
| diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c |
| index 138dfb8..174486b 100644 |
| --- a/drivers/net/enic/enic_rxtx.c |
| +++ b/drivers/net/enic/enic_rxtx.c |
| @@ -251,6 +251,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, |
| struct vnic_cq *cq; |
| volatile struct cq_desc *cqd_ptr; |
| uint8_t color; |
| + uint16_t nb_err = 0; |
| |
| cq = &enic->cq[enic_cq_rq(enic, rq->index)]; |
| rx_id = cq->to_clean; /* index of cqd, rqd, mbuf_table */ |
| @@ -278,10 +279,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, |
| /* allocate a new mbuf */ |
| nmb = rte_rxmbuf_alloc(rq->mp); |
| if (nmb == NULL) { |
| - dev_err(enic, "RX mbuf alloc failed port=%u qid=%u", |
| - enic->port_id, (unsigned)rq->index); |
| - rte_eth_devices[enic->port_id]. |
| - data->rx_mbuf_alloc_failed++; |
| + rte_atomic64_inc(&enic->soft_stats.rx_nombuf); |
| break; |
| } |
| |
| @@ -323,9 +321,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, |
| rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd); |
| enic_cq_rx_to_pkt_flags(&cqd, rxmb); |
| } else { |
| - rxmb->pkt_len = 0; |
| - rxmb->packet_type = 0; |
| - rxmb->ol_flags = 0; |
| + rte_pktmbuf_free(rxmb); |
| + rte_atomic64_inc(&enic->soft_stats.rx_packet_errors); |
| + nb_err++; |
| + continue; |
| } |
| rxmb->data_len = rxmb->pkt_len; |
| |
| @@ -337,7 +336,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, |
| rx_pkts[nb_rx++] = rxmb; |
| } |
| |
| - nb_hold += nb_rx; |
| + nb_hold += nb_rx + nb_err; |
| cq->to_clean = rx_id; |
| |
| if (nb_hold > rq->rx_free_thresh) { |
| -- |
| 2.7.4 |
| |