examples/qos_sched: add TC and queue config flexibility
[dpdk.git] / examples / qos_sched / stats.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <unistd.h>
6 #include <string.h>
7
8 #include "main.h"
9
10 int
11 qavg_q(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, uint8_t tc,
12                 uint8_t q)
13 {
14         struct rte_sched_queue_stats stats;
15         struct rte_sched_port *port;
16         uint16_t qlen;
17         uint32_t count, i, queue_id = 0;
18         uint32_t average;
19
20         for (i = 0; i < nb_pfc; i++) {
21                 if (qos_conf[i].tx_port == port_id)
22                         break;
23         }
24
25         if (i == nb_pfc ||
26                 subport_id >= port_params.n_subports_per_port ||
27                 pipe_id >= port_params.n_pipes_per_subport  ||
28                 tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE ||
29                 q >= RTE_SCHED_BE_QUEUES_PER_PIPE ||
30                 (tc < RTE_SCHED_TRAFFIC_CLASS_BE && q > 0))
31                 return -1;
32
33         port = qos_conf[i].sched_port;
34         for (i = 0; i < subport_id; i++)
35                 queue_id += port_params.n_pipes_per_subport *
36                                 RTE_SCHED_QUEUES_PER_PIPE;
37         if (tc < RTE_SCHED_TRAFFIC_CLASS_BE)
38                 queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc;
39         else
40                 queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc + q;
41
42         average = 0;
43         for (count = 0; count < qavg_ntimes; count++) {
44                 rte_sched_queue_read_stats(port, queue_id, &stats, &qlen);
45                 average += qlen;
46                 usleep(qavg_period);
47         }
48
49         average /= qavg_ntimes;
50
51         printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average);
52
53         return 0;
54 }
55
56 int
57 qavg_tcpipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id,
58                 uint8_t tc)
59 {
60         struct rte_sched_queue_stats stats;
61         struct rte_sched_port *port;
62         uint16_t qlen;
63         uint32_t count, i, queue_id = 0;
64         uint32_t average, part_average;
65
66         for (i = 0; i < nb_pfc; i++) {
67                 if (qos_conf[i].tx_port == port_id)
68                         break;
69         }
70
71         if (i == nb_pfc || subport_id >= port_params.n_subports_per_port ||
72                 pipe_id >= port_params.n_pipes_per_subport ||
73                 tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
74                 return -1;
75
76         port = qos_conf[i].sched_port;
77
78         for (i = 0; i < subport_id; i++)
79                 queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE;
80
81         queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc;
82
83         average = 0;
84
85         for (count = 0; count < qavg_ntimes; count++) {
86                 part_average = 0;
87
88                 if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) {
89                         rte_sched_queue_read_stats(port, queue_id,
90                                 &stats, &qlen);
91                         part_average += qlen;
92                 } else {
93                         for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) {
94                                 rte_sched_queue_read_stats(port, queue_id + i,
95                                         &stats, &qlen);
96                                 part_average += qlen;
97                         }
98                         average += part_average / RTE_SCHED_BE_QUEUES_PER_PIPE;
99                 }
100                 usleep(qavg_period);
101         }
102
103         average /= qavg_ntimes;
104
105         printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average);
106
107         return 0;
108 }
109
110 int
111 qavg_pipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id)
112 {
113         struct rte_sched_queue_stats stats;
114         struct rte_sched_port *port;
115         uint16_t qlen;
116         uint32_t count, i, queue_id = 0;
117         uint32_t average, part_average;
118
119         for (i = 0; i < nb_pfc; i++) {
120                 if (qos_conf[i].tx_port == port_id)
121                         break;
122         }
123
124         if (i == nb_pfc ||
125                 subport_id >= port_params.n_subports_per_port ||
126                 pipe_id >= port_params.n_pipes_per_subport)
127                 return -1;
128
129         port = qos_conf[i].sched_port;
130
131         for (i = 0; i < subport_id; i++)
132                 queue_id += port_params.n_pipes_per_subport *
133                                 RTE_SCHED_QUEUES_PER_PIPE;
134
135         queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE;
136
137         average = 0;
138
139         for (count = 0; count < qavg_ntimes; count++) {
140                 part_average = 0;
141                 for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) {
142                         rte_sched_queue_read_stats(port, queue_id + i,
143                                 &stats, &qlen);
144                         part_average += qlen;
145                 }
146                 average += part_average / RTE_SCHED_QUEUES_PER_PIPE;
147                 usleep(qavg_period);
148         }
149
150         average /= qavg_ntimes;
151
152         printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average);
153
154         return 0;
155 }
156
157 int
158 qavg_tcsubport(uint16_t port_id, uint32_t subport_id, uint8_t tc)
159 {
160         struct rte_sched_queue_stats stats;
161         struct rte_sched_port *port;
162         uint16_t qlen;
163         uint32_t queue_id, count, i, j, subport_queue_id = 0;
164         uint32_t average, part_average;
165
166         for (i = 0; i < nb_pfc; i++) {
167                 if (qos_conf[i].tx_port == port_id)
168                         break;
169         }
170
171         if (i == nb_pfc ||
172                 subport_id >= port_params.n_subports_per_port ||
173                 tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
174                 return -1;
175
176         port = qos_conf[i].sched_port;
177
178         for (i = 0; i < subport_id; i++)
179                 subport_queue_id +=
180                         port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE;
181
182         average = 0;
183
184         for (count = 0; count < qavg_ntimes; count++) {
185                 part_average = 0;
186                 for (i = 0; i < port_params.n_pipes_per_subport; i++) {
187                         if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) {
188                                 queue_id = subport_queue_id +
189                                         i * RTE_SCHED_QUEUES_PER_PIPE + tc;
190                                 rte_sched_queue_read_stats(port, queue_id,
191                                         &stats, &qlen);
192                                 part_average += qlen;
193                         } else {
194                                 for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
195                                         queue_id = subport_queue_id +
196                                                         i * RTE_SCHED_QUEUES_PER_PIPE +
197                                                         tc + j;
198                                         rte_sched_queue_read_stats(port, queue_id,
199                                                 &stats, &qlen);
200                                         part_average += qlen;
201                                 }
202                         }
203                 }
204
205                 if (tc < RTE_SCHED_TRAFFIC_CLASS_BE)
206                         average += part_average / (port_params.n_pipes_per_subport);
207                 else
208                         average +=
209                                 part_average / (port_params.n_pipes_per_subport) *
210                                 RTE_SCHED_BE_QUEUES_PER_PIPE;
211
212                 usleep(qavg_period);
213         }
214
215         average /= qavg_ntimes;
216
217         printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average);
218
219         return 0;
220 }
221
222 int
223 qavg_subport(uint16_t port_id, uint32_t subport_id)
224 {
225         struct rte_sched_queue_stats stats;
226         struct rte_sched_port *port;
227         uint16_t qlen;
228         uint32_t queue_id, count, i, j, subport_queue_id = 0;
229         uint32_t average, part_average;
230
231         for (i = 0; i < nb_pfc; i++) {
232                 if (qos_conf[i].tx_port == port_id)
233                         break;
234         }
235
236         if (i == nb_pfc ||
237                 subport_id >= port_params.n_subports_per_port)
238                 return -1;
239
240         port = qos_conf[i].sched_port;
241
242         for (i = 0; i < subport_id; i++)
243                 subport_queue_id += port_params.n_pipes_per_subport *
244                         RTE_SCHED_QUEUES_PER_PIPE;
245
246         average = 0;
247
248         for (count = 0; count < qavg_ntimes; count++) {
249                 part_average = 0;
250                 for (i = 0; i < port_params.n_pipes_per_subport; i++) {
251                         queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE;
252
253                         for (j = 0; j < RTE_SCHED_QUEUES_PER_PIPE; j++) {
254                                 rte_sched_queue_read_stats(port, queue_id + j,
255                                         &stats, &qlen);
256                                 part_average += qlen;
257                         }
258                 }
259
260                 average += part_average /
261                         (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE);
262                 usleep(qavg_period);
263         }
264
265         average /= qavg_ntimes;
266
267         printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average);
268
269         return 0;
270 }
271
272 int
273 subport_stat(uint16_t port_id, uint32_t subport_id)
274 {
275         struct rte_sched_subport_stats stats;
276         struct rte_sched_port *port;
277         uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
278         uint8_t i;
279
280         for (i = 0; i < nb_pfc; i++) {
281                 if (qos_conf[i].tx_port == port_id)
282                         break;
283         }
284
285         if (i == nb_pfc || subport_id >= port_params.n_subports_per_port)
286                 return -1;
287
288         port = qos_conf[i].sched_port;
289         memset(tc_ov, 0, sizeof(tc_ov));
290
291         rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov);
292
293         printf("\n");
294         printf("+----+-------------+-------------+-------------+-------------+-------------+\n");
295         printf("| TC |   Pkts OK   |Pkts Dropped |  Bytes OK   |Bytes Dropped|  OV Status  |\n");
296         printf("+----+-------------+-------------+-------------+-------------+-------------+\n");
297
298         for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
299                 printf("|  %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n",
300                         i, stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i],
301                 stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]);
302                 printf("+----+-------------+-------------+-------------+-------------+-------------+\n");
303         }
304         printf("\n");
305
306         return 0;
307 }
308
309 int
310 pipe_stat(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id)
311 {
312         struct rte_sched_queue_stats stats;
313         struct rte_sched_port *port;
314         uint16_t qlen;
315         uint8_t i, j;
316         uint32_t queue_id = 0;
317
318         for (i = 0; i < nb_pfc; i++) {
319                 if (qos_conf[i].tx_port == port_id)
320                         break;
321         }
322
323         if (i == nb_pfc ||
324                 subport_id >= port_params.n_subports_per_port ||
325                 pipe_id >= port_params.n_pipes_per_subport)
326                 return -1;
327
328         port = qos_conf[i].sched_port;
329         for (i = 0; i < subport_id; i++)
330                 queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE;
331
332         queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE;
333
334         printf("\n");
335         printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n");
336         printf("| TC | Queue |   Pkts OK   |Pkts Dropped |  Bytes OK   |Bytes Dropped|    Length   |\n");
337         printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n");
338
339         for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
340                 if (i < RTE_SCHED_TRAFFIC_CLASS_BE) {
341                         rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen);
342                         printf("|  %d |   %d   | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n",
343                                 i, 0, stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes,
344                                 stats.n_bytes_dropped, qlen);
345                         printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n");
346                 } else {
347                         for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) {
348                                 rte_sched_queue_read_stats(port, queue_id + i + j,
349                                         &stats, &qlen);
350                                 printf("|  %d |   %d   | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n",
351                                         i, j, stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes,
352                                         stats.n_bytes_dropped, qlen);
353                                 printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n");
354                         }
355                 }
356         }
357         printf("\n");
358
359         return 0;
360 }