summaryrefslogtreecommitdiffstats
path: root/dpdk/dpdk-16.04_patches/0015-ENIC-counter-improvement.patch
blob: 721fd107c6fe144f86e00e025e382361dac27d24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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