721fd107c6fe144f86e00e025e382361dac27d24
[vpp.git] / dpdk / dpdk-16.04_patches / 0015-ENIC-counter-improvement.patch
1 From 30a3d6e23880094edfc51b49b11099c8b8bfa8cd Mon Sep 17 00:00:00 2001
2 From: John Lo <loj@cisco.com>
3 Date: Tue, 7 Jun 2016 12:36:23 +0200
4 Subject: [PATCH 15/17] ENIC counter improvement
5
6 ---
7  drivers/net/enic/enic.h      |  7 +++++++
8  drivers/net/enic/enic_main.c | 38 ++++++++++++++++++++++++++++++++++----
9  drivers/net/enic/enic_rxtx.c | 15 +++++++--------
10  3 files changed, 48 insertions(+), 12 deletions(-)
11
12 diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
13 index 43b82a6..7c1b5c9 100644
14 --- a/drivers/net/enic/enic.h
15 +++ b/drivers/net/enic/enic.h
16 @@ -91,6 +91,11 @@ struct enic_fdir {
17         struct enic_fdir_node *nodes[ENICPMD_FDIR_MAX];
18  };
19  
20 +struct enic_soft_stats {
21 +       rte_atomic64_t rx_nombuf;
22 +       rte_atomic64_t rx_packet_errors;
23 +};
24 +
25  /* Per-instance private data structure */
26  struct enic {
27         struct enic *next;
28 @@ -133,6 +138,8 @@ struct enic {
29         /* interrupt resource */
30         struct vnic_intr intr;
31         unsigned int intr_count;
32 +
33 +       struct enic_soft_stats soft_stats;
34  };
35  
36  static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq)
37 diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
38 index 9bfdec1..a00565a 100644
39 --- a/drivers/net/enic/enic_main.c
40 +++ b/drivers/net/enic/enic_main.c
41 @@ -142,22 +142,51 @@ static void enic_log_q_error(struct enic *enic)
42  }
43  
44  
45 +static void enic_clear_soft_stats(struct enic *enic)
46 +{
47 +       struct enic_soft_stats *soft_stats = &enic->soft_stats;
48 +       rte_atomic64_clear(&soft_stats->rx_nombuf);
49 +       rte_atomic64_clear(&soft_stats->rx_packet_errors);
50 +}
51 +
52 +static void enic_init_soft_stats(struct enic *enic)
53 +{
54 +       struct enic_soft_stats *soft_stats = &enic->soft_stats;
55 +       rte_atomic64_init(&soft_stats->rx_nombuf);
56 +       rte_atomic64_init(&soft_stats->rx_packet_errors);
57 +       enic_clear_soft_stats(enic);
58 +}
59 +
60  void enic_dev_stats_clear(struct enic *enic)
61  {
62         if (vnic_dev_stats_clear(enic->vdev))
63                 dev_err(enic, "Error in clearing stats\n");
64 +       enic_clear_soft_stats(enic);
65  }
66  
67  void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats)
68  {
69         struct vnic_stats *stats;
70 +       struct enic_soft_stats *soft_stats = &enic->soft_stats;
71 +       int64_t rx_truncated;
72 +       uint64_t rx_packet_errors;
73  
74         if (vnic_dev_stats_dump(enic->vdev, &stats)) {
75                 dev_err(enic, "Error in getting stats\n");
76                 return;
77         }
78  
79 -       r_stats->ipackets = stats->rx.rx_frames_ok;
80 +       /* The number of truncated packets can only be calculated by
81 +        * subtracting a hardware counter from error packets received by
82 +        * the driver. Note: this causes transient inaccuracies in the
83 +        * ipackets count. Also, the length of truncated packets are
84 +        * counted in ibytes even though truncated packets are dropped
85 +        * which can make ibytes be slightly higher than it should be.
86 +        */
87 +       rx_packet_errors = rte_atomic64_read(&soft_stats->rx_packet_errors);
88 +       rx_truncated = rx_packet_errors - stats->rx.rx_errors;
89 +
90 +       r_stats->ipackets = stats->rx.rx_frames_ok - rx_truncated;
91         r_stats->opackets = stats->tx.tx_frames_ok;
92  
93         r_stats->ibytes = stats->rx.rx_bytes_ok;
94 @@ -166,10 +195,9 @@ void enic_dev_stats_get(struct enic *enic, struct rte_eth_stats *r_stats)
95         r_stats->ierrors = stats->rx.rx_errors + stats->rx.rx_drop;
96         r_stats->oerrors = stats->tx.tx_errors;
97  
98 -       r_stats->imissed = stats->rx.rx_no_bufs;
99 +       r_stats->imissed = stats->rx.rx_no_bufs + rx_truncated;
100  
101 -       r_stats->imcasts = stats->rx.rx_multicast_frames_ok;
102 -       r_stats->rx_nombuf = stats->rx.rx_no_bufs;
103 +       r_stats->rx_nombuf = rte_atomic64_read(&soft_stats->rx_nombuf);
104  }
105  
106  void enic_del_mac_address(struct enic *enic)
107 @@ -755,6 +783,8 @@ int enic_setup_finish(struct enic *enic)
108  {
109         int ret;
110  
111 +       enic_init_soft_stats(enic);
112 +
113         ret = enic_set_rss_nic_cfg(enic);
114         if (ret) {
115                 dev_err(enic, "Failed to config nic, aborting.\n");
116 diff --git a/drivers/net/enic/enic_rxtx.c b/drivers/net/enic/enic_rxtx.c
117 index 138dfb8..174486b 100644
118 --- a/drivers/net/enic/enic_rxtx.c
119 +++ b/drivers/net/enic/enic_rxtx.c
120 @@ -251,6 +251,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
121         struct vnic_cq *cq;
122         volatile struct cq_desc *cqd_ptr;
123         uint8_t color;
124 +       uint16_t nb_err = 0;
125  
126         cq = &enic->cq[enic_cq_rq(enic, rq->index)];
127         rx_id = cq->to_clean;           /* index of cqd, rqd, mbuf_table */
128 @@ -278,10 +279,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
129                 /* allocate a new mbuf */
130                 nmb = rte_rxmbuf_alloc(rq->mp);
131                 if (nmb == NULL) {
132 -                       dev_err(enic, "RX mbuf alloc failed port=%u qid=%u",
133 -                       enic->port_id, (unsigned)rq->index);
134 -                       rte_eth_devices[enic->port_id].
135 -                                       data->rx_mbuf_alloc_failed++;
136 +                       rte_atomic64_inc(&enic->soft_stats.rx_nombuf);
137                         break;
138                 }
139  
140 @@ -323,9 +321,10 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
141                         rxmb->packet_type = enic_cq_rx_flags_to_pkt_type(&cqd);
142                         enic_cq_rx_to_pkt_flags(&cqd, rxmb);
143                 } else {
144 -                       rxmb->pkt_len = 0;
145 -                       rxmb->packet_type = 0;
146 -                       rxmb->ol_flags = 0;
147 +                       rte_pktmbuf_free(rxmb);
148 +                       rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
149 +                       nb_err++;
150 +                       continue;
151                 }
152                 rxmb->data_len = rxmb->pkt_len;
153  
154 @@ -337,7 +336,7 @@ enic_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
155                 rx_pkts[nb_rx++] = rxmb;
156         }
157  
158 -       nb_hold += nb_rx;
159 +       nb_hold += nb_rx + nb_err;
160         cq->to_clean = rx_id;
161  
162         if (nb_hold > rq->rx_free_thresh) {
163 -- 
164 2.7.4
165