New upstream version 18.02
[deb_dpdk.git] / examples / ip_pipeline / config_check.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4
5 #include <stdio.h>
6
7 #include <rte_ip.h>
8
9 #include "app.h"
10
11 static void
12 check_mempools(struct app_params *app)
13 {
14         uint32_t i;
15
16         for (i = 0; i < app->n_mempools; i++) {
17                 struct app_mempool_params *p = &app->mempool_params[i];
18
19                 APP_CHECK((p->pool_size > 0),
20                         "Mempool %s size is 0\n", p->name);
21
22                 APP_CHECK((p->cache_size > 0),
23                         "Mempool %s cache size is 0\n", p->name);
24
25                 APP_CHECK(rte_is_power_of_2(p->cache_size),
26                         "Mempool %s cache size not a power of 2\n", p->name);
27         }
28 }
29
30 static inline uint32_t
31 link_rxq_used(struct app_link_params *link, uint32_t q_id)
32 {
33         uint32_t i;
34
35         if ((link->arp_q == q_id) ||
36                 (link->tcp_syn_q == q_id) ||
37                 (link->ip_local_q == q_id) ||
38                 (link->tcp_local_q == q_id) ||
39                 (link->udp_local_q == q_id) ||
40                 (link->sctp_local_q == q_id))
41                 return 1;
42
43         for (i = 0; i < link->n_rss_qs; i++)
44                 if (link->rss_qs[i] == q_id)
45                         return 1;
46
47         return 0;
48 }
49
50 static void
51 check_links(struct app_params *app)
52 {
53         uint32_t i;
54
55         /* Check that number of links matches the port mask */
56         if (app->port_mask) {
57                 uint32_t n_links_port_mask =
58                         __builtin_popcountll(app->port_mask);
59
60                 APP_CHECK((app->n_links == n_links_port_mask),
61                         "Not enough links provided in the PORT_MASK\n");
62         }
63
64         for (i = 0; i < app->n_links; i++) {
65                 struct app_link_params *link = &app->link_params[i];
66                 uint32_t rxq_max, n_rxq, n_txq, link_id, i;
67
68                 APP_PARAM_GET_ID(link, "LINK", link_id);
69
70                 /* Check that link RXQs are contiguous */
71                 rxq_max = 0;
72                 if (link->arp_q > rxq_max)
73                         rxq_max = link->arp_q;
74                 if (link->tcp_syn_q > rxq_max)
75                         rxq_max = link->tcp_syn_q;
76                 if (link->ip_local_q > rxq_max)
77                         rxq_max = link->ip_local_q;
78                 if (link->tcp_local_q > rxq_max)
79                         rxq_max = link->tcp_local_q;
80                 if (link->udp_local_q > rxq_max)
81                         rxq_max = link->udp_local_q;
82                 if (link->sctp_local_q > rxq_max)
83                         rxq_max = link->sctp_local_q;
84                 for (i = 0; i < link->n_rss_qs; i++)
85                         if (link->rss_qs[i] > rxq_max)
86                                 rxq_max = link->rss_qs[i];
87
88                 for (i = 1; i <= rxq_max; i++)
89                         APP_CHECK((link_rxq_used(link, i)),
90                                 "%s RXQs are not contiguous (A)\n", link->name);
91
92                 n_rxq = app_link_get_n_rxq(app, link);
93
94                 APP_CHECK((n_rxq), "%s does not have any RXQ\n", link->name);
95
96                 APP_CHECK((n_rxq == rxq_max + 1),
97                         "%s RXQs are not contiguous (B)\n", link->name);
98
99                 for (i = 0; i < n_rxq; i++) {
100                         char name[APP_PARAM_NAME_SIZE];
101                         int pos;
102
103                         sprintf(name, "RXQ%" PRIu32 ".%" PRIu32,
104                                 link_id, i);
105                         pos = APP_PARAM_FIND(app->hwq_in_params, name);
106                         APP_CHECK((pos >= 0),
107                                 "%s RXQs are not contiguous (C)\n", link->name);
108                 }
109
110                 /* Check that link TXQs are contiguous */
111                 n_txq = app_link_get_n_txq(app, link);
112
113                 APP_CHECK((n_txq),  "%s does not have any TXQ\n", link->name);
114
115                 for (i = 0; i < n_txq; i++) {
116                         char name[APP_PARAM_NAME_SIZE];
117                         int pos;
118
119                         sprintf(name, "TXQ%" PRIu32 ".%" PRIu32,
120                                 link_id, i);
121                         pos = APP_PARAM_FIND(app->hwq_out_params, name);
122                         APP_CHECK((pos >= 0),
123                                 "%s TXQs are not contiguous\n", link->name);
124                 }
125         }
126 }
127
128 static void
129 check_rxqs(struct app_params *app)
130 {
131         uint32_t i;
132
133         for (i = 0; i < app->n_pktq_hwq_in; i++) {
134                 struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i];
135                 uint32_t n_readers = app_rxq_get_readers(app, p);
136
137                 APP_CHECK((p->size > 0),
138                         "%s size is 0\n", p->name);
139
140                 APP_CHECK((rte_is_power_of_2(p->size)),
141                         "%s size is not a power of 2\n", p->name);
142
143                 APP_CHECK((p->burst > 0),
144                         "%s burst size is 0\n", p->name);
145
146                 APP_CHECK((p->burst <= p->size),
147                         "%s burst size is bigger than its size\n", p->name);
148
149                 APP_CHECK((n_readers != 0),
150                         "%s has no reader\n", p->name);
151
152                 APP_CHECK((n_readers == 1),
153                         "%s has more than one reader\n", p->name);
154         }
155 }
156
157 static void
158 check_txqs(struct app_params *app)
159 {
160         uint32_t i;
161
162         for (i = 0; i < app->n_pktq_hwq_out; i++) {
163                 struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i];
164                 uint32_t n_writers = app_txq_get_writers(app, p);
165
166                 APP_CHECK((p->size > 0),
167                         "%s size is 0\n", p->name);
168
169                 APP_CHECK((rte_is_power_of_2(p->size)),
170                         "%s size is not a power of 2\n", p->name);
171
172                 APP_CHECK((p->burst > 0),
173                         "%s burst size is 0\n", p->name);
174
175                 APP_CHECK((p->burst <= p->size),
176                         "%s burst size is bigger than its size\n", p->name);
177
178                 APP_CHECK((n_writers != 0),
179                         "%s has no writer\n", p->name);
180
181                 APP_CHECK((n_writers == 1),
182                         "%s has more than one writer\n", p->name);
183         }
184 }
185
186 static void
187 check_swqs(struct app_params *app)
188 {
189         uint32_t i;
190
191         for (i = 0; i < app->n_pktq_swq; i++) {
192                 struct app_pktq_swq_params *p = &app->swq_params[i];
193                 uint32_t n_readers = app_swq_get_readers(app, p);
194                 uint32_t n_writers = app_swq_get_writers(app, p);
195                 uint32_t n_flags;
196
197                 APP_CHECK((p->size > 0),
198                         "%s size is 0\n", p->name);
199
200                 APP_CHECK((rte_is_power_of_2(p->size)),
201                         "%s size is not a power of 2\n", p->name);
202
203                 APP_CHECK((p->burst_read > 0),
204                         "%s read burst size is 0\n", p->name);
205
206                 APP_CHECK((p->burst_read <= p->size),
207                         "%s read burst size is bigger than its size\n",
208                         p->name);
209
210                 APP_CHECK((p->burst_write > 0),
211                         "%s write burst size is 0\n", p->name);
212
213                 APP_CHECK((p->burst_write <= p->size),
214                         "%s write burst size is bigger than its size\n",
215                         p->name);
216
217                 APP_CHECK((n_readers != 0),
218                         "%s has no reader\n", p->name);
219
220                 if (n_readers > 1)
221                         APP_LOG(app, LOW, "%s has more than one reader", p->name);
222
223                 APP_CHECK((n_writers != 0),
224                         "%s has no writer\n", p->name);
225
226                 if (n_writers > 1)
227                         APP_LOG(app, LOW, "%s has more than one writer", p->name);
228
229                 n_flags = p->ipv4_frag + p->ipv6_frag + p->ipv4_ras + p->ipv6_ras;
230
231                 APP_CHECK((n_flags < 2),
232                         "%s has more than one fragmentation or reassembly mode enabled\n",
233                         p->name);
234
235                 APP_CHECK((!((n_readers > 1) && (n_flags == 1))),
236                         "%s has more than one reader when fragmentation or reassembly"
237                         " mode enabled\n",
238                         p->name);
239
240                 APP_CHECK((!((n_writers > 1) && (n_flags == 1))),
241                         "%s has more than one writer when fragmentation or reassembly"
242                         " mode enabled\n",
243                         p->name);
244
245                 n_flags = p->ipv4_ras + p->ipv6_ras;
246
247                 APP_CHECK((!((p->dropless == 1) && (n_flags == 1))),
248                         "%s has dropless when reassembly mode enabled\n", p->name);
249
250                 n_flags = p->ipv4_frag + p->ipv6_frag;
251
252                 if (n_flags == 1) {
253                         uint16_t ip_hdr_size = (p->ipv4_frag) ? sizeof(struct ipv4_hdr) :
254                                 sizeof(struct ipv6_hdr);
255
256                         APP_CHECK((p->mtu > ip_hdr_size),
257                                 "%s mtu size is smaller than ip header\n", p->name);
258
259                         APP_CHECK((!((p->mtu - ip_hdr_size) % 8)),
260                                 "%s mtu size is incorrect\n", p->name);
261                 }
262         }
263 }
264
265 static void
266 check_tms(struct app_params *app)
267 {
268         uint32_t i;
269
270         for (i = 0; i < app->n_pktq_tm; i++) {
271                 struct app_pktq_tm_params *p = &app->tm_params[i];
272                 uint32_t n_readers = app_tm_get_readers(app, p);
273                 uint32_t n_writers = app_tm_get_writers(app, p);
274
275                 APP_CHECK((n_readers != 0),
276                         "%s has no reader\n", p->name);
277
278                 APP_CHECK((n_readers == 1),
279                         "%s has more than one reader\n", p->name);
280
281                 APP_CHECK((n_writers != 0),
282                         "%s has no writer\n", p->name);
283
284                 APP_CHECK((n_writers == 1),
285                         "%s has more than one writer\n", p->name);
286         }
287 }
288
289 static void
290 check_taps(struct app_params *app)
291 {
292         uint32_t i;
293
294         for (i = 0; i < app->n_pktq_tap; i++) {
295                 struct app_pktq_tap_params *p = &app->tap_params[i];
296                 uint32_t n_readers = app_tap_get_readers(app, p);
297                 uint32_t n_writers = app_tap_get_writers(app, p);
298
299                 APP_CHECK((n_readers != 0),
300                         "%s has no reader\n", p->name);
301
302                 APP_CHECK((n_readers == 1),
303                         "%s has more than one reader\n", p->name);
304
305                 APP_CHECK((n_writers != 0),
306                         "%s has no writer\n", p->name);
307
308                 APP_CHECK((n_writers == 1),
309                         "%s has more than one writer\n", p->name);
310
311                 APP_CHECK((p->burst_read > 0),
312                         "%s read burst size is 0\n", p->name);
313
314                 APP_CHECK((p->burst_write > 0),
315                         "%s write burst size is 0\n", p->name);
316         }
317 }
318
319 static void
320 check_knis(struct app_params *app) {
321         uint32_t i;
322
323         for (i = 0; i < app->n_pktq_kni; i++) {
324                 struct app_pktq_kni_params *p = &app->kni_params[i];
325                 uint32_t n_readers = app_kni_get_readers(app, p);
326                 uint32_t n_writers = app_kni_get_writers(app, p);
327
328                 APP_CHECK((n_readers != 0),
329                         "%s has no reader\n", p->name);
330
331                 APP_CHECK((n_readers == 1),
332                         "%s has more than one reader\n", p->name);
333
334                 APP_CHECK((n_writers != 0),
335                         "%s has no writer\n", p->name);
336
337                 APP_CHECK((n_writers == 1),
338                         "%s has more than one writer\n", p->name);
339         }
340 }
341
342 static void
343 check_sources(struct app_params *app)
344 {
345         uint32_t i;
346
347         for (i = 0; i < app->n_pktq_source; i++) {
348                 struct app_pktq_source_params *p = &app->source_params[i];
349                 uint32_t n_readers = app_source_get_readers(app, p);
350
351                 APP_CHECK((n_readers != 0),
352                         "%s has no reader\n", p->name);
353
354                 APP_CHECK((n_readers == 1),
355                         "%s has more than one reader\n", p->name);
356         }
357 }
358
359 static void
360 check_sinks(struct app_params *app)
361 {
362         uint32_t i;
363
364         for (i = 0; i < app->n_pktq_sink; i++) {
365                 struct app_pktq_sink_params *p = &app->sink_params[i];
366                 uint32_t n_writers = app_sink_get_writers(app, p);
367
368                 APP_CHECK((n_writers != 0),
369                         "%s has no writer\n", p->name);
370
371                 APP_CHECK((n_writers == 1),
372                         "%s has more than one writer\n", p->name);
373         }
374 }
375
376 static void
377 check_msgqs(struct app_params *app)
378 {
379         uint32_t i;
380
381         for (i = 0; i < app->n_msgq; i++) {
382                 struct app_msgq_params *p = &app->msgq_params[i];
383                 uint32_t n_readers = app_msgq_get_readers(app, p);
384                 uint32_t n_writers = app_msgq_get_writers(app, p);
385                 uint32_t msgq_req_pipeline, msgq_rsp_pipeline;
386                 uint32_t msgq_req_core, msgq_rsp_core;
387
388                 APP_CHECK((p->size > 0),
389                         "%s size is 0\n", p->name);
390
391                 APP_CHECK((rte_is_power_of_2(p->size)),
392                         "%s size is not a power of 2\n", p->name);
393
394                 msgq_req_pipeline = (strncmp(p->name, "MSGQ-REQ-PIPELINE",
395                         strlen("MSGQ-REQ-PIPELINE")) == 0);
396
397                 msgq_rsp_pipeline = (strncmp(p->name, "MSGQ-RSP-PIPELINE",
398                         strlen("MSGQ-RSP-PIPELINE")) == 0);
399
400                 msgq_req_core = (strncmp(p->name, "MSGQ-REQ-CORE",
401                         strlen("MSGQ-REQ-CORE")) == 0);
402
403                 msgq_rsp_core = (strncmp(p->name, "MSGQ-RSP-CORE",
404                         strlen("MSGQ-RSP-CORE")) == 0);
405
406                 if ((msgq_req_pipeline == 0) &&
407                         (msgq_rsp_pipeline == 0) &&
408                         (msgq_req_core == 0) &&
409                         (msgq_rsp_core == 0)) {
410                         APP_CHECK((n_readers != 0),
411                                 "%s has no reader\n", p->name);
412
413                         APP_CHECK((n_readers == 1),
414                                 "%s has more than one reader\n", p->name);
415
416                         APP_CHECK((n_writers != 0),
417                                 "%s has no writer\n", p->name);
418
419                         APP_CHECK((n_writers == 1),
420                                 "%s has more than one writer\n", p->name);
421                 }
422
423                 if (msgq_req_pipeline) {
424                         struct app_pipeline_params *pipeline;
425                         uint32_t pipeline_id;
426
427                         APP_PARAM_GET_ID(p, "MSGQ-REQ-PIPELINE", pipeline_id);
428
429                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
430                                 "PIPELINE",
431                                 pipeline_id,
432                                 pipeline);
433
434                         APP_CHECK((pipeline != NULL),
435                                 "%s is not associated with a valid pipeline\n",
436                                 p->name);
437                 }
438
439                 if (msgq_rsp_pipeline) {
440                         struct app_pipeline_params *pipeline;
441                         uint32_t pipeline_id;
442
443                         APP_PARAM_GET_ID(p, "MSGQ-RSP-PIPELINE", pipeline_id);
444
445                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
446                                 "PIPELINE",
447                                 pipeline_id,
448                                 pipeline);
449
450                         APP_CHECK((pipeline != NULL),
451                                 "%s is not associated with a valid pipeline\n",
452                                 p->name);
453                 }
454         }
455 }
456
457 static void
458 check_pipelines(struct app_params *app)
459 {
460         uint32_t i;
461
462         for (i = 0; i < app->n_pipelines; i++) {
463                 struct app_pipeline_params *p = &app->pipeline_params[i];
464
465                 APP_CHECK((p->n_msgq_in == p->n_msgq_out),
466                         "%s number of input MSGQs does not match "
467                         "the number of output MSGQs\n", p->name);
468         }
469 }
470
471 int
472 app_config_check(struct app_params *app)
473 {
474         check_mempools(app);
475         check_links(app);
476         check_rxqs(app);
477         check_txqs(app);
478         check_swqs(app);
479         check_tms(app);
480         check_taps(app);
481         check_knis(app);
482         check_sources(app);
483         check_sinks(app);
484         check_msgqs(app);
485         check_pipelines(app);
486
487         return 0;
488 }