1ff57637239d9d503845817e96c7f7073446c0e0
[dpdk.git] / examples / ip_pipeline / config_check.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 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 void
60 check_links(struct app_params *app)
61 {
62         uint32_t n_links_port_mask = __builtin_popcountll(app->port_mask);
63         uint32_t i;
64
65         /* Check that number of links matches the port mask */
66         APP_CHECK((app->n_links == n_links_port_mask),
67                 "Not enough links provided in the PORT_MASK\n");
68
69         for (i = 0; i < app->n_links; i++) {
70                 struct app_link_params *link = &app->link_params[i];
71                 uint32_t rxq_max, n_rxq, n_txq, link_id, i;
72
73                 APP_PARAM_GET_ID(link, "LINK", link_id);
74
75                 /* Check that link RXQs are contiguous */
76                 rxq_max = 0;
77                 if (link->arp_q > rxq_max)
78                         rxq_max = link->arp_q;
79                 if (link->tcp_syn_local_q > rxq_max)
80                         rxq_max = link->tcp_syn_local_q;
81                 if (link->ip_local_q > rxq_max)
82                         rxq_max = link->ip_local_q;
83                 if (link->tcp_local_q > rxq_max)
84                         rxq_max = link->tcp_local_q;
85                 if (link->udp_local_q > rxq_max)
86                         rxq_max = link->udp_local_q;
87                 if (link->sctp_local_q > rxq_max)
88                         rxq_max = link->sctp_local_q;
89
90                 for (i = 1; i <= rxq_max; i++)
91                         APP_CHECK(((link->arp_q == i) ||
92                                 (link->tcp_syn_local_q == i) ||
93                                 (link->ip_local_q == i) ||
94                                 (link->tcp_local_q == i) ||
95                                 (link->udp_local_q == i) ||
96                                 (link->sctp_local_q == i)),
97                                 "%s RXQs are not contiguous (A)\n", link->name);
98
99                 n_rxq = app_link_get_n_rxq(app, link);
100
101                 APP_CHECK((n_rxq), "%s does not have any RXQ\n", link->name);
102
103                 APP_CHECK((n_rxq == rxq_max + 1),
104                         "%s RXQs are not contiguous (B)\n", link->name);
105
106                 for (i = 0; i < n_rxq; i++) {
107                         char name[APP_PARAM_NAME_SIZE];
108                         int pos;
109
110                         sprintf(name, "RXQ%" PRIu32 ".%" PRIu32,
111                                 link_id, i);
112                         pos = APP_PARAM_FIND(app->hwq_in_params, name);
113                         APP_CHECK((pos >= 0),
114                                 "%s RXQs are not contiguous (C)\n", link->name);
115                 }
116
117                 /* Check that link RXQs are contiguous */
118                 n_txq = app_link_get_n_txq(app, link);
119
120                 APP_CHECK((n_txq),  "%s does not have any TXQ\n", link->name);
121
122                 for (i = 0; i < n_txq; i++) {
123                         char name[APP_PARAM_NAME_SIZE];
124                         int pos;
125
126                         sprintf(name, "TXQ%" PRIu32 ".%" PRIu32,
127                                 link_id, i);
128                         pos = APP_PARAM_FIND(app->hwq_out_params, name);
129                         APP_CHECK((pos >= 0),
130                                 "%s TXQs are not contiguous\n", link->name);
131                 }
132         }
133 }
134
135 static void
136 check_rxqs(struct app_params *app)
137 {
138         uint32_t i;
139
140         for (i = 0; i < app->n_pktq_hwq_in; i++) {
141                 struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i];
142                 uint32_t n_readers = app_rxq_get_readers(app, p);
143
144                 APP_CHECK((p->size > 0),
145                         "%s size is 0\n", p->name);
146
147                 APP_CHECK((rte_is_power_of_2(p->size)),
148                         "%s size is not a power of 2\n", p->name);
149
150                 APP_CHECK((p->burst > 0),
151                         "%s burst size is 0\n", p->name);
152
153                 APP_CHECK((p->burst <= p->size),
154                         "%s burst size is bigger than its size\n", p->name);
155
156                 APP_CHECK((n_readers != 0),
157                         "%s has no reader\n", p->name);
158
159                 APP_CHECK((n_readers == 1),
160                         "%s has more than one reader\n", p->name);
161         }
162 }
163
164 static void
165 check_txqs(struct app_params *app)
166 {
167         uint32_t i;
168
169         for (i = 0; i < app->n_pktq_hwq_out; i++) {
170                 struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i];
171                 uint32_t n_writers = app_txq_get_writers(app, p);
172
173                 APP_CHECK((p->size > 0),
174                         "%s size is 0\n", p->name);
175
176                 APP_CHECK((rte_is_power_of_2(p->size)),
177                         "%s size is not a power of 2\n", p->name);
178
179                 APP_CHECK((p->burst > 0),
180                         "%s burst size is 0\n", p->name);
181
182                 APP_CHECK((p->burst <= p->size),
183                         "%s burst size is bigger than its size\n", p->name);
184
185                 APP_CHECK((n_writers != 0),
186                         "%s has no writer\n", p->name);
187
188                 APP_CHECK((n_writers == 1),
189                         "%s has more than one writer\n", p->name);
190         }
191 }
192
193 static void
194 check_swqs(struct app_params *app)
195 {
196         uint32_t i;
197
198         for (i = 0; i < app->n_pktq_swq; i++) {
199                 struct app_pktq_swq_params *p = &app->swq_params[i];
200                 uint32_t n_readers = app_swq_get_readers(app, p);
201                 uint32_t n_writers = app_swq_get_writers(app, p);
202                 uint32_t n_flags;
203
204                 APP_CHECK((p->size > 0),
205                         "%s size is 0\n", p->name);
206
207                 APP_CHECK((rte_is_power_of_2(p->size)),
208                         "%s size is not a power of 2\n", p->name);
209
210                 APP_CHECK((p->burst_read > 0),
211                         "%s read burst size is 0\n", p->name);
212
213                 APP_CHECK((p->burst_read <= p->size),
214                         "%s read burst size is bigger than its size\n",
215                         p->name);
216
217                 APP_CHECK((p->burst_write > 0),
218                         "%s write burst size is 0\n", p->name);
219
220                 APP_CHECK((p->burst_write <= p->size),
221                         "%s write burst size is bigger than its size\n",
222                         p->name);
223
224                 APP_CHECK((n_readers != 0),
225                         "%s has no reader\n", p->name);
226
227                 if (n_readers > 1)
228                         APP_LOG(app, LOW, "%s has more than one reader", p->name);
229
230                 APP_CHECK((n_writers != 0),
231                         "%s has no writer\n", p->name);
232
233                 if (n_writers > 1)
234                         APP_LOG(app, LOW, "%s has more than one writer", p->name);
235
236                 n_flags = p->ipv4_frag + p->ipv6_frag + p->ipv4_ras + p->ipv6_ras;
237
238                 APP_CHECK((n_flags < 2),
239                         "%s has more than one fragmentation or reassembly mode enabled\n",
240                         p->name);
241
242                 APP_CHECK((!((n_readers > 1) && (n_flags == 1))),
243                         "%s has more than one reader when fragmentation or reassembly"
244                         " mode enabled\n",
245                         p->name);
246
247                 APP_CHECK((!((n_writers > 1) && (n_flags == 1))),
248                         "%s has more than one writer when fragmentation or reassembly"
249                         " mode enabled\n",
250                         p->name);
251
252                 n_flags = p->ipv4_ras + p->ipv6_ras;
253
254                 APP_CHECK((!((p->dropless == 1) && (n_flags == 1))),
255                         "%s has dropless when reassembly mode enabled\n", p->name);
256
257                 n_flags = p->ipv4_frag + p->ipv6_frag;
258
259                 if (n_flags == 1) {
260                         uint16_t ip_hdr_size = (p->ipv4_frag) ? sizeof(struct ipv4_hdr) :
261                                 sizeof(struct ipv6_hdr);
262
263                         APP_CHECK((p->mtu > ip_hdr_size),
264                                 "%s mtu size is smaller than ip header\n", p->name);
265
266                         APP_CHECK((!((p->mtu - ip_hdr_size) % 8)),
267                                 "%s mtu size is incorrect\n", p->name);
268                 }
269         }
270 }
271
272 static void
273 check_tms(struct app_params *app)
274 {
275         uint32_t i;
276
277         for (i = 0; i < app->n_pktq_tm; i++) {
278                 struct app_pktq_tm_params *p = &app->tm_params[i];
279                 uint32_t n_readers = app_tm_get_readers(app, p);
280                 uint32_t n_writers = app_tm_get_writers(app, p);
281
282                 APP_CHECK((n_readers != 0),
283                         "%s has no reader\n", p->name);
284
285                 APP_CHECK((n_readers == 1),
286                         "%s has more than one reader\n", p->name);
287
288                 APP_CHECK((n_writers != 0),
289                         "%s has no writer\n", p->name);
290
291                 APP_CHECK((n_writers == 1),
292                         "%s has more than one writer\n", p->name);
293         }
294 }
295
296 static void
297 check_sources(struct app_params *app)
298 {
299         uint32_t i;
300
301         for (i = 0; i < app->n_pktq_source; i++) {
302                 struct app_pktq_source_params *p = &app->source_params[i];
303                 uint32_t n_readers = app_source_get_readers(app, p);
304
305                 APP_CHECK((n_readers != 0),
306                         "%s has no reader\n", p->name);
307
308                 APP_CHECK((n_readers == 1),
309                         "%s has more than one reader\n", p->name);
310         }
311 }
312
313 static void
314 check_sinks(struct app_params *app)
315 {
316         uint32_t i;
317
318         for (i = 0; i < app->n_pktq_sink; i++) {
319                 struct app_pktq_sink_params *p = &app->sink_params[i];
320                 uint32_t n_writers = app_sink_get_writers(app, p);
321
322                 APP_CHECK((n_writers != 0),
323                         "%s has no writer\n", p->name);
324
325                 APP_CHECK((n_writers == 1),
326                         "%s has more than one writer\n", p->name);
327         }
328 }
329
330 static void
331 check_msgqs(struct app_params *app)
332 {
333         uint32_t i;
334
335         for (i = 0; i < app->n_msgq; i++) {
336                 struct app_msgq_params *p = &app->msgq_params[i];
337                 uint32_t n_readers = app_msgq_get_readers(app, p);
338                 uint32_t n_writers = app_msgq_get_writers(app, p);
339                 uint32_t msgq_req_pipeline, msgq_rsp_pipeline;
340                 uint32_t msgq_req_core, msgq_rsp_core;
341
342                 APP_CHECK((p->size > 0),
343                         "%s size is 0\n", p->name);
344
345                 APP_CHECK((rte_is_power_of_2(p->size)),
346                         "%s size is not a power of 2\n", p->name);
347
348                 msgq_req_pipeline = (strncmp(p->name, "MSGQ-REQ-PIPELINE",
349                         strlen("MSGQ-REQ-PIPELINE")) == 0);
350
351                 msgq_rsp_pipeline = (strncmp(p->name, "MSGQ-RSP-PIPELINE",
352                         strlen("MSGQ-RSP-PIPELINE")) == 0);
353
354                 msgq_req_core = (strncmp(p->name, "MSGQ-REQ-CORE",
355                         strlen("MSGQ-REQ-CORE")) == 0);
356
357                 msgq_rsp_core = (strncmp(p->name, "MSGQ-RSP-CORE",
358                         strlen("MSGQ-RSP-CORE")) == 0);
359
360                 if ((msgq_req_pipeline == 0) &&
361                         (msgq_rsp_pipeline == 0) &&
362                         (msgq_req_core == 0) &&
363                         (msgq_rsp_core == 0)) {
364                         APP_CHECK((n_readers != 0),
365                                 "%s has no reader\n", p->name);
366
367                         APP_CHECK((n_readers == 1),
368                                 "%s has more than one reader\n", p->name);
369
370                         APP_CHECK((n_writers != 0),
371                                 "%s has no writer\n", p->name);
372
373                         APP_CHECK((n_writers == 1),
374                                 "%s has more than one writer\n", p->name);
375                 }
376
377                 if (msgq_req_pipeline) {
378                         struct app_pipeline_params *pipeline;
379                         uint32_t pipeline_id;
380
381                         APP_PARAM_GET_ID(p, "MSGQ-REQ-PIPELINE", pipeline_id);
382
383                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
384                                 "PIPELINE",
385                                 pipeline_id,
386                                 pipeline);
387
388                         APP_CHECK((pipeline != NULL),
389                                 "%s is not associated with a valid pipeline\n",
390                                 p->name);
391                 }
392
393                 if (msgq_rsp_pipeline) {
394                         struct app_pipeline_params *pipeline;
395                         uint32_t pipeline_id;
396
397                         APP_PARAM_GET_ID(p, "MSGQ-RSP-PIPELINE", pipeline_id);
398
399                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
400                                 "PIPELINE",
401                                 pipeline_id,
402                                 pipeline);
403
404                         APP_CHECK((pipeline != NULL),
405                                 "%s is not associated with a valid pipeline\n",
406                                 p->name);
407                 }
408         }
409 }
410
411 static void
412 check_pipelines(struct app_params *app)
413 {
414         uint32_t i;
415
416         for (i = 0; i < app->n_pipelines; i++) {
417                 struct app_pipeline_params *p = &app->pipeline_params[i];
418
419                 APP_CHECK((p->n_msgq_in == p->n_msgq_out),
420                         "%s number of input MSGQs does not match "
421                         "the number of output MSGQs\n", p->name);
422         }
423 }
424
425 int
426 app_config_check(struct app_params *app)
427 {
428         check_mempools(app);
429         check_links(app);
430         check_rxqs(app);
431         check_txqs(app);
432         check_swqs(app);
433         check_tms(app);
434         check_sources(app);
435         check_sinks(app);
436         check_msgqs(app);
437         check_pipelines(app);
438
439         return 0;
440 }