Merge "Initial support for DPDK 18.05"
[samplevnf.git] / VNFs / DPPD-PROX / display_ports.c
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <rte_cycles.h>
18
19 #include "clock.h"
20 #include "display_ports.h"
21 #include "display.h"
22 #include "stats_port.h"
23 #include "prox_globals.h"
24 #include "prox_port_cfg.h"
25
26 static struct display_page display_page_ports;
27 static struct display_column *nb_col;
28 static struct display_column *name_col;
29 static struct display_column *type_col;
30
31 static struct display_column *no_mbufs_col;
32 static struct display_column *ierrors_col;
33 static struct display_column *imissed_col;
34 static struct display_column *oerrors_col;
35 static struct display_column *rx_col;
36 static struct display_column *tx_col;
37 static struct display_column *rx_bytes_col;
38 static struct display_column *tx_bytes_col;
39 static struct display_column *rx_percent_col;
40 static struct display_column *tx_percent_col;
41
42 static int port_disp[PROX_MAX_PORTS];
43 static int n_port_disp;
44
45 static void display_ports_draw_frame(struct screen_state *state)
46 {
47         n_port_disp = 0;
48         for (uint8_t i = 0; i < PROX_MAX_PORTS; ++i) {
49                 if (prox_port_cfg[i].active) {
50                         port_disp[n_port_disp++] = i;
51                 }
52         }
53
54         const uint32_t n_ports = stats_get_n_ports();
55         char name[32];
56         char *ptr;
57
58         display_page_init(&display_page_ports);
59
60         struct display_table *port = display_page_add_table(&display_page_ports);
61         struct display_table *stats = display_page_add_table(&display_page_ports);
62
63         display_table_init(port, "Port");
64
65         nb_col = display_table_add_col(port);
66         name_col = display_table_add_col(port);
67         type_col = display_table_add_col(port);
68
69         display_column_init(nb_col, "Nb", 4);
70         display_column_init(name_col, "Name", 8);
71         display_column_init(type_col, "Type", 7);
72
73         if (state->toggle == 0) {
74                 display_table_init(stats, "Statistics per second");
75                 no_mbufs_col = display_table_add_col(stats);
76                 ierrors_col = display_table_add_col(stats);
77                 imissed_col = display_table_add_col(stats);
78                 oerrors_col = display_table_add_col(stats);
79                 rx_col = display_table_add_col(stats);
80                 tx_col = display_table_add_col(stats);
81                 rx_bytes_col = display_table_add_col(stats);
82                 tx_bytes_col = display_table_add_col(stats);
83                 rx_percent_col = display_table_add_col(stats);
84                 tx_percent_col = display_table_add_col(stats);
85
86                 display_column_init(no_mbufs_col, "no mbufs (#)", 12);
87                 display_column_init(ierrors_col, "ierrors (#)", 12);
88                 display_column_init(imissed_col, "imissed (#)", 12);
89                 display_column_init(oerrors_col, "oerrors (#)", 12);
90                 display_column_init(rx_col, "RX (Kpps)", 10);
91                 display_column_init(tx_col, "TX (Kpps)", 10);
92                 display_column_init(rx_bytes_col, "RX (Kbps)", 10);
93                 display_column_init(tx_bytes_col, "TX (Kbps)", 10);
94                 display_column_init(rx_percent_col, "RX (%)", 8);
95                 display_column_init(tx_percent_col, "TX (%)", 8);
96         } else {
97                 display_table_init(stats, "Total statistics");
98                 no_mbufs_col = display_table_add_col(stats);
99                 ierrors_col = display_table_add_col(stats);
100                 imissed_col = display_table_add_col(stats);
101                 oerrors_col = display_table_add_col(stats);
102                 rx_col = display_table_add_col(stats);
103                 tx_col = display_table_add_col(stats);
104
105                 display_column_init(no_mbufs_col, "no mbufs (#)", 13);
106                 display_column_init(ierrors_col, "ierrors (#)", 13);
107                 display_column_init(imissed_col, "imissed (#)", 13);
108                 display_column_init(oerrors_col, "oerrors (#)", 13);
109                 display_column_init(rx_col, "RX (#)", 13);
110                 display_column_init(tx_col, "TX (#)", 13);
111         }
112
113         display_page_draw_frame(&display_page_ports, n_port_disp);
114         for (uint8_t i = 0; i < n_port_disp; ++i) {
115                 const uint32_t port_id = port_disp[i];
116
117                 display_column_print(nb_col, i, "%u", port_id);
118                 display_column_print(name_col, i, "%s", prox_port_cfg[port_id].name);
119                 display_column_print(type_col, i, "%s", prox_port_cfg[port_id].short_name);
120         }
121 }
122
123 struct percent {
124         uint32_t percent;
125         uint32_t part;
126 };
127
128 static struct percent calc_percent(uint64_t val, uint64_t delta_t)
129 {
130         struct percent ret;
131         uint64_t normalized = 0;
132
133         if (val == 0) {
134                 ret.percent = 0;
135                 ret.part = 0;
136         } else if (val < thresh) {
137                 ret.percent = val * tsc_hz / delta_t / 12500000;
138                 ret.part = (val * tsc_hz / delta_t / 1250) % 10000;
139         } else if (delta_t > tsc_hz) {
140                 ret.percent = val / (delta_t / tsc_hz) / 12500000;
141                 ret.part = (val / (delta_t / tsc_hz) / 1250) % 10000;
142         } else {
143                 ret.percent = 0;
144                 ret.part = 0;
145         }
146         return ret;
147 }
148
149 static void display_ports_draw_per_sec_stats(void)
150 {
151         for (uint8_t i = 0; i < n_port_disp; ++i) {
152                 const uint32_t port_id = port_disp[i];
153                 struct port_stats_sample *last = stats_get_port_stats_sample(port_id, 1);
154                 struct port_stats_sample *prev = stats_get_port_stats_sample(port_id, 0);
155
156                 uint64_t delta_t = last->tsc - prev->tsc;
157
158                 /* This could happen if we just reset the screen.
159                    stats will be updated later */
160                 if (delta_t == 0)
161                         continue;
162
163                 uint64_t no_mbufs_rate = val_to_rate(last->no_mbufs - prev->no_mbufs, delta_t);
164                 uint64_t ierrors_rate = val_to_rate(last->ierrors - prev->ierrors, delta_t);
165                 uint64_t imissed_rate = val_to_rate(last->imissed - prev->imissed, delta_t);
166                 uint64_t oerrors_rate = val_to_rate(last->oerrors - prev->oerrors, delta_t);
167
168                 uint64_t rx_kbps_rate = val_to_rate((last->rx_bytes - prev->rx_bytes) * 8, delta_t) / 1000;
169                 uint64_t tx_kbps_rate = val_to_rate((last->tx_bytes - prev->tx_bytes) * 8, delta_t) / 1000;
170
171                 uint64_t rx_rate = val_to_rate(last->rx_tot - prev->rx_tot, delta_t) / 1000;
172                 if (unlikely(prev->rx_tot > last->rx_tot))
173                         rx_rate = 0;
174                 uint64_t tx_rate = val_to_rate(last->tx_tot - prev->tx_tot, delta_t) / 1000;
175                 if (unlikely(prev->tx_tot > last->tx_tot))
176                         tx_rate = 0;
177
178                 /* Take 20 bytes overhead (or 24 if crc strip is enabled) into accound */
179                 struct percent rx_percent;
180                 struct percent tx_percent;
181                 if (strcmp(prox_port_cfg[port_id].short_name, "i40e") == 0) {
182                         if (prox_port_cfg[port_id].port_conf.rxmode.hw_strip_crc == 1) {
183                                 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 24 * (last->rx_tot - prev->rx_tot), delta_t);
184                                 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
185                         } else {
186                                 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
187                                 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
188                         }
189                 } else {
190                         if (prox_port_cfg[port_id].port_conf.rxmode.hw_strip_crc == 1) {
191                                 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 24 * (last->rx_tot - prev->rx_tot), delta_t);
192                                 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
193                         } else {
194                                 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
195                                 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
196                         }
197                 }
198
199                 display_column_print(no_mbufs_col, i, "%lu", no_mbufs_rate);
200                 display_column_print(ierrors_col, i, "%lu", ierrors_rate);
201                 display_column_print(imissed_col, i, "%lu", imissed_rate);
202                 display_column_print(oerrors_col, i, "%lu", oerrors_rate);
203
204                 display_column_print(rx_bytes_col, i, "%lu", rx_kbps_rate);
205                 display_column_print(tx_bytes_col, i, "%lu", tx_kbps_rate);
206                 display_column_print(rx_col, i, "%lu", rx_rate);
207                 display_column_print(tx_col, i, "%lu", tx_rate);
208
209                 display_column_print(rx_percent_col, i, "%3u.%04u", rx_percent.percent, rx_percent.part);
210                 display_column_print(tx_percent_col, i, "%3u.%04u", tx_percent.percent, tx_percent.part);
211         }
212 }
213
214 static void display_ports_draw_total_stats(void)
215 {
216         for (uint8_t i = 0; i < n_port_disp; ++i) {
217                 const uint32_t port_id = port_disp[i];
218                 struct port_stats_sample *last = stats_get_port_stats_sample(port_id, 1);
219
220                 display_column_print(no_mbufs_col, i, "%lu", last->no_mbufs);
221                 display_column_print(ierrors_col, i, "%lu", last->ierrors);
222                 display_column_print(imissed_col, i, "%lu", last->imissed);
223                 display_column_print(oerrors_col, i, "%lu", last->oerrors);
224                 display_column_print(rx_col, i, "%lu", last->rx_tot);
225                 display_column_print(tx_col, i, "%lu", last->tx_tot);
226         }
227 }
228
229 static void display_ports_draw_stats(struct screen_state *state)
230 {
231         if (state->toggle == 0)
232                 display_ports_draw_per_sec_stats();
233         else
234                 display_ports_draw_total_stats();
235 }
236
237 static int display_ports_get_height(void)
238 {
239         return stats_get_n_ports();
240 }
241
242 static struct display_screen display_screen_ports = {
243         .draw_frame = display_ports_draw_frame,
244         .draw_stats = display_ports_draw_stats,
245         .get_height = display_ports_get_height,
246         .title = "ports",
247 };
248
249 struct display_screen *display_ports(void)
250 {
251         return &display_screen_ports;
252 }