aboutsummaryrefslogtreecommitdiffstats
path: root/dpdk/dpdk-16.04_patches/0015-enic-counter_improvement.patch
blob: 6c8986bbb1bfb76058cb85e08c785aa1b0c4102b (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
diff -ur dpdk-16.04.orig/drivers/net/enic/enic.h dpdk-16.04/drivers/net/enic/enic.h
--- dpdk-16.04.orig/drivers/net/enic/enic.h	2016-05-26 16:59:16.531326660 -0700
+++ dpdk-16.04/drivers/net/enic/enic.h	2016-05-26 16:59:52.689262489 -0700
@@ -91,6 +91,11 @@
 	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 @@
 	/* 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 -ur dpdk-16.04.orig/drivers/net/enic/enic_main.c dpdk-16.04/drivers/net/enic/enic_main.c
--- dpdk-16.04.orig/drivers/net/enic/enic_main.c	2016-05-26 16:59:16.533326822 -0700
+++ dpdk-16.04/drivers/net/enic/enic_main.c	2016-05-26 17:08:11.768801926 -0700
@@ -142,22 +142,51 @@
 }
 
 
+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 @@
 	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 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 -ur dpdk-16.04.orig/drivers/net/enic/enic_rxtx.c dpdk-16.04/drivers/net/enic/enic_rxtx.c
--- dpdk-16.04.orig/drivers/net/enic/enic_rxtx.c	2016-05-26 16:59:16.522325929 -0700
+++ dpdk-16.04/drivers/net/enic/enic_rxtx.c	2016-05-26 16:59:52.694262896 -0700
@@ -251,6 +251,7 @@
 	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 @@
 		/* 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 @@
 			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 @@
 		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) {