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