2 // Copyright (c) 2010-2017 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <rte_cycles.h>
20 #include "display_ports.h"
22 #include "stats_port.h"
23 #include "prox_globals.h"
24 #include "prox_port_cfg.h"
25 #include "prox_compat.h"
27 static struct display_page display_page_ports;
28 static struct display_column *nb_col;
29 static struct display_column *name_col;
30 static struct display_column *type_col;
32 static struct display_column *no_mbufs_col;
33 static struct display_column *ierrors_col;
34 static struct display_column *imissed_col;
35 static struct display_column *oerrors_col;
36 static struct display_column *rx_col;
37 static struct display_column *tx_col;
38 static struct display_column *rx_bytes_col;
39 static struct display_column *tx_bytes_col;
40 static struct display_column *rx_percent_col;
41 static struct display_column *tx_percent_col;
43 static int port_disp[PROX_MAX_PORTS];
44 static int n_port_disp;
46 static void display_ports_draw_frame(struct screen_state *state)
49 for (uint8_t i = 0; i < PROX_MAX_PORTS; ++i) {
50 if (prox_port_cfg[i].active) {
51 port_disp[n_port_disp++] = i;
55 const uint32_t n_ports = stats_get_n_ports();
59 display_page_init(&display_page_ports);
61 struct display_table *port = display_page_add_table(&display_page_ports);
62 struct display_table *stats = display_page_add_table(&display_page_ports);
64 display_table_init(port, "Port");
66 nb_col = display_table_add_col(port);
67 name_col = display_table_add_col(port);
68 type_col = display_table_add_col(port);
70 display_column_init(nb_col, "Nb", 4);
71 display_column_init(name_col, "Name", 8);
72 display_column_init(type_col, "Type", 7);
74 if (state->toggle == 0) {
75 display_table_init(stats, "Statistics per second");
76 no_mbufs_col = display_table_add_col(stats);
77 ierrors_col = display_table_add_col(stats);
78 imissed_col = display_table_add_col(stats);
79 oerrors_col = display_table_add_col(stats);
80 rx_col = display_table_add_col(stats);
81 tx_col = display_table_add_col(stats);
82 rx_bytes_col = display_table_add_col(stats);
83 tx_bytes_col = display_table_add_col(stats);
84 rx_percent_col = display_table_add_col(stats);
85 tx_percent_col = display_table_add_col(stats);
87 display_column_init(no_mbufs_col, "no mbufs (#)", 12);
88 display_column_init(ierrors_col, "ierrors (#)", 12);
89 display_column_init(imissed_col, "imissed (#)", 12);
90 display_column_init(oerrors_col, "oerrors (#)", 12);
91 display_column_init(rx_col, "RX (Kpps)", 10);
92 display_column_init(tx_col, "TX (Kpps)", 10);
93 display_column_init(rx_bytes_col, "RX (Kbps)", 10);
94 display_column_init(tx_bytes_col, "TX (Kbps)", 10);
95 display_column_init(rx_percent_col, "RX (%)", 8);
96 display_column_init(tx_percent_col, "TX (%)", 8);
98 display_table_init(stats, "Total statistics");
99 no_mbufs_col = display_table_add_col(stats);
100 ierrors_col = display_table_add_col(stats);
101 imissed_col = display_table_add_col(stats);
102 oerrors_col = display_table_add_col(stats);
103 rx_col = display_table_add_col(stats);
104 tx_col = display_table_add_col(stats);
106 display_column_init(no_mbufs_col, "no mbufs (#)", 13);
107 display_column_init(ierrors_col, "ierrors (#)", 13);
108 display_column_init(imissed_col, "imissed (#)", 13);
109 display_column_init(oerrors_col, "oerrors (#)", 13);
110 display_column_init(rx_col, "RX (#)", 13);
111 display_column_init(tx_col, "TX (#)", 13);
114 display_page_draw_frame(&display_page_ports, n_port_disp);
115 for (uint8_t i = 0; i < n_port_disp; ++i) {
116 const uint32_t port_id = port_disp[i];
118 display_column_print(nb_col, i, "%u", port_id);
119 display_column_print(name_col, i, "%s", prox_port_cfg[port_id].names[0]);
120 display_column_print(type_col, i, "%s", prox_port_cfg[port_id].short_name);
129 static struct percent calc_percent(uint64_t val, uint64_t delta_t)
132 uint64_t normalized = 0;
137 } else if (val < thresh) {
138 ret.percent = val * tsc_hz / delta_t / 12500000;
139 ret.part = (val * tsc_hz / delta_t / 1250) % 10000;
140 } else if (delta_t > tsc_hz) {
141 ret.percent = val / (delta_t / tsc_hz) / 12500000;
142 ret.part = (val / (delta_t / tsc_hz) / 1250) % 10000;
150 static void display_ports_draw_per_sec_stats(void)
152 for (uint8_t i = 0; i < n_port_disp; ++i) {
153 const uint32_t port_id = port_disp[i];
154 struct port_stats_sample *last = stats_get_port_stats_sample(port_id, 1);
155 struct port_stats_sample *prev = stats_get_port_stats_sample(port_id, 0);
157 uint64_t delta_t = last->tsc - prev->tsc;
159 /* This could happen if we just reset the screen.
160 stats will be updated later */
164 uint64_t no_mbufs_rate = val_to_rate(last->no_mbufs - prev->no_mbufs, delta_t);
165 uint64_t ierrors_rate = val_to_rate(last->ierrors - prev->ierrors, delta_t);
166 uint64_t imissed_rate = val_to_rate(last->imissed - prev->imissed, delta_t);
167 uint64_t oerrors_rate = val_to_rate(last->oerrors - prev->oerrors, delta_t);
169 uint64_t rx_kbps_rate = val_to_rate((last->rx_bytes - prev->rx_bytes) * 8, delta_t) / 1000;
170 uint64_t tx_kbps_rate = val_to_rate((last->tx_bytes - prev->tx_bytes) * 8, delta_t) / 1000;
172 uint64_t rx_rate = val_to_rate(last->rx_tot - prev->rx_tot, delta_t) / 1000;
173 if (unlikely(prev->rx_tot > last->rx_tot))
175 uint64_t tx_rate = val_to_rate(last->tx_tot - prev->tx_tot, delta_t) / 1000;
176 if (unlikely(prev->tx_tot > last->tx_tot))
179 /* Take 20 bytes overhead (or 24 if crc strip is enabled) into accound */
180 struct percent rx_percent;
181 struct percent tx_percent;
182 if (strcmp(prox_port_cfg[port_id].short_name, "i40e_vf") == 0) {
183 #if defined (DEV_RX_OFFLOAD_CRC_STRIP)
184 if (prox_port_cfg[port_id].requested_rx_offload & DEV_RX_OFFLOAD_CRC_STRIP) {
185 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
186 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
188 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
189 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
192 if (prox_port_cfg[port_id].requested_rx_offload & DEV_RX_OFFLOAD_CRC_STRIP) {
193 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 24 * (last->rx_tot - prev->rx_tot), delta_t);
194 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
196 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
197 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
201 #if defined DEV_RX_OFFLOAD_KEEP_CRC
202 if (prox_port_cfg[port_id].requested_rx_offload & DEV_RX_OFFLOAD_KEEP_CRC ) {
203 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
204 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
206 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
207 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
210 if (prox_port_cfg[port_id].requested_rx_offload & DEV_RX_OFFLOAD_KEEP_CRC ) {
211 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 20 * (last->rx_tot - prev->rx_tot), delta_t);
212 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 20 * (last->tx_tot - prev->tx_tot), delta_t);
214 rx_percent = calc_percent(last->rx_bytes - prev->rx_bytes + 24 * (last->rx_tot - prev->rx_tot), delta_t);
215 tx_percent = calc_percent(last->tx_bytes - prev->tx_bytes + 24 * (last->tx_tot - prev->tx_tot), delta_t);
219 #error neither DEV_RX_OFFLOAD_CRC_STRIP or DEV_RX_OFFLOAD_KEEP_CRC is defined
223 display_column_print(no_mbufs_col, i, "%lu", no_mbufs_rate);
224 display_column_print(ierrors_col, i, "%lu", ierrors_rate);
225 display_column_print(imissed_col, i, "%lu", imissed_rate);
226 display_column_print(oerrors_col, i, "%lu", oerrors_rate);
228 display_column_print(rx_bytes_col, i, "%lu", rx_kbps_rate);
229 display_column_print(tx_bytes_col, i, "%lu", tx_kbps_rate);
230 display_column_print(rx_col, i, "%lu", rx_rate);
231 display_column_print(tx_col, i, "%lu", tx_rate);
233 display_column_print(rx_percent_col, i, "%3u.%04u", rx_percent.percent, rx_percent.part);
234 display_column_print(tx_percent_col, i, "%3u.%04u", tx_percent.percent, tx_percent.part);
238 static void display_ports_draw_total_stats(void)
240 for (uint8_t i = 0; i < n_port_disp; ++i) {
241 const uint32_t port_id = port_disp[i];
242 struct port_stats_sample *last = stats_get_port_stats_sample(port_id, 1);
244 display_column_print(no_mbufs_col, i, "%lu", last->no_mbufs);
245 display_column_print(ierrors_col, i, "%lu", last->ierrors);
246 display_column_print(imissed_col, i, "%lu", last->imissed);
247 display_column_print(oerrors_col, i, "%lu", last->oerrors);
248 display_column_print(rx_col, i, "%lu", last->rx_tot);
249 display_column_print(tx_col, i, "%lu", last->tx_tot);
253 static void display_ports_draw_stats(struct screen_state *state)
255 if (state->toggle == 0)
256 display_ports_draw_per_sec_stats();
258 display_ports_draw_total_stats();
261 static int display_ports_get_height(void)
263 return stats_get_n_ports();
266 static struct display_screen display_screen_ports = {
267 .draw_frame = display_ports_draw_frame,
268 .draw_stats = display_ports_draw_stats,
269 .get_height = display_ports_get_height,
273 struct display_screen *display_ports(void)
275 return &display_screen_ports;