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