examples/ip_pipeline: add config file checks
[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 "app.h"
37
38 static void
39 check_mempools(struct app_params *app)
40 {
41         uint32_t i;
42
43         for (i = 0; i < app->n_mempools; i++) {
44                 struct app_mempool_params *p = &app->mempool_params[i];
45
46                 APP_CHECK((p->pool_size > 0),
47                         "Mempool %s size is 0\n", p->name);
48
49                 APP_CHECK((p->cache_size > 0),
50                         "Mempool %s cache size is 0\n", p->name);
51
52                 APP_CHECK(rte_is_power_of_2(p->cache_size),
53                         "Mempool %s cache size not a power of 2\n", p->name);
54         }
55 }
56
57 static void
58 check_links(struct app_params *app)
59 {
60         uint32_t n_links_port_mask = __builtin_popcountll(app->port_mask);
61         uint32_t i;
62
63         /* Check that number of links matches the port mask */
64         APP_CHECK((app->n_links == n_links_port_mask),
65                 "Not enough links provided in the PORT_MASK\n");
66
67         for (i = 0; i < app->n_links; i++) {
68                 struct app_link_params *link = &app->link_params[i];
69                 uint32_t rxq_max, n_rxq, n_txq, link_id, i;
70
71                 APP_PARAM_GET_ID(link, "LINK", link_id);
72
73                 /* Check that link RXQs are contiguous */
74                 rxq_max = 0;
75                 if (link->arp_q > rxq_max)
76                         rxq_max = link->arp_q;
77                 if (link->tcp_syn_local_q > rxq_max)
78                         rxq_max = link->tcp_syn_local_q;
79                 if (link->ip_local_q > rxq_max)
80                         rxq_max = link->ip_local_q;
81                 if (link->tcp_local_q > rxq_max)
82                         rxq_max = link->tcp_local_q;
83                 if (link->udp_local_q > rxq_max)
84                         rxq_max = link->udp_local_q;
85                 if (link->sctp_local_q > rxq_max)
86                         rxq_max = link->sctp_local_q;
87
88                 for (i = 1; i <= rxq_max; i++)
89                         APP_CHECK(((link->arp_q == i) ||
90                                 (link->tcp_syn_local_q == i) ||
91                                 (link->ip_local_q == i) ||
92                                 (link->tcp_local_q == i) ||
93                                 (link->udp_local_q == i) ||
94                                 (link->sctp_local_q == i)),
95                                 "%s RXQs are not contiguous (A)\n", link->name);
96
97                 n_rxq = app_link_get_n_rxq(app, link);
98
99                 APP_CHECK((n_rxq == rxq_max + 1),
100                         "%s RXQs are not contiguous (B)\n", link->name);
101
102                 for (i = 0; i < n_rxq; i++) {
103                         char name[APP_PARAM_NAME_SIZE];
104                         int pos;
105
106                         sprintf(name, "RXQ%" PRIu32 ".%" PRIu32,
107                                 link_id, i);
108                         pos = APP_PARAM_FIND(app->hwq_in_params, name);
109                         APP_CHECK((pos >= 0),
110                                 "%s RXQs are not contiguous (C)\n", link->name);
111                 }
112
113                 /* Check that link RXQs are contiguous */
114                 n_txq = app_link_get_n_txq(app, link);
115
116                 for (i = 0; i < n_txq; i++) {
117                         char name[APP_PARAM_NAME_SIZE];
118                         int pos;
119
120                         sprintf(name, "TXQ%" PRIu32 ".%" PRIu32,
121                                 link_id, i);
122                         pos = APP_PARAM_FIND(app->hwq_out_params, name);
123                         APP_CHECK((pos >= 0),
124                                 "%s TXQs are not contiguous\n", link->name);
125                 }
126         }
127 }
128
129 static void
130 check_rxqs(struct app_params *app)
131 {
132         uint32_t i;
133
134         for (i = 0; i < app->n_pktq_hwq_in; i++) {
135                 struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i];
136                 uint32_t n_readers = app_rxq_get_readers(app, p);
137
138                 APP_CHECK((p->size > 0),
139                         "%s size is 0\n", p->name);
140
141                 APP_CHECK((rte_is_power_of_2(p->size)),
142                         "%s size is not a power of 2\n", p->name);
143
144                 APP_CHECK((p->burst > 0),
145                         "%s burst size is 0\n", p->name);
146
147                 APP_CHECK((p->burst <= p->size),
148                         "%s burst size is bigger than its size\n", p->name);
149
150                 APP_CHECK((n_readers != 0),
151                         "%s has no reader\n", p->name);
152
153                 APP_CHECK((n_readers == 1),
154                         "%s has more than one reader\n", p->name);
155         }
156 }
157
158 static void
159 check_txqs(struct app_params *app)
160 {
161         uint32_t i;
162
163         for (i = 0; i < app->n_pktq_hwq_out; i++) {
164                 struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i];
165                 uint32_t n_writers = app_txq_get_writers(app, p);
166
167                 APP_CHECK((p->size > 0),
168                         "%s size is 0\n", p->name);
169
170                 APP_CHECK((rte_is_power_of_2(p->size)),
171                         "%s size is not a power of 2\n", p->name);
172
173                 APP_CHECK((p->burst > 0),
174                         "%s burst size is 0\n", p->name);
175
176                 APP_CHECK((p->burst <= p->size),
177                         "%s burst size is bigger than its size\n", p->name);
178
179                 APP_CHECK((n_writers != 0),
180                         "%s has no writer\n", p->name);
181
182                 APP_CHECK((n_writers == 1),
183                         "%s has more than one writer\n", p->name);
184         }
185 }
186
187 static void
188 check_swqs(struct app_params *app)
189 {
190         uint32_t i;
191
192         for (i = 0; i < app->n_pktq_swq; i++) {
193                 struct app_pktq_swq_params *p = &app->swq_params[i];
194                 uint32_t n_readers = app_swq_get_readers(app, p);
195                 uint32_t n_writers = app_swq_get_writers(app, p);
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                 APP_CHECK((n_readers == 1),
221                         "%s has more than one reader\n", p->name);
222
223                 APP_CHECK((n_writers != 0),
224                         "%s has no writer\n", p->name);
225
226                 APP_CHECK((n_writers == 1),
227                         "%s has more than one writer\n", p->name);
228         }
229 }
230
231 static void
232 check_tms(struct app_params *app)
233 {
234         uint32_t i;
235
236         for (i = 0; i < app->n_pktq_tm; i++) {
237                 struct app_pktq_tm_params *p = &app->tm_params[i];
238                 uint32_t n_readers = app_tm_get_readers(app, p);
239                 uint32_t n_writers = app_tm_get_writers(app, p);
240
241                 APP_CHECK((n_readers != 0),
242                         "%s has no reader\n", p->name);
243
244                 APP_CHECK((n_readers == 1),
245                         "%s has more than one reader\n", p->name);
246
247                 APP_CHECK((n_writers != 0),
248                         "%s has no writer\n", p->name);
249
250                 APP_CHECK((n_writers == 1),
251                         "%s has more than one writer\n", p->name);
252         }
253 }
254
255 static void
256 check_sources(struct app_params *app)
257 {
258         uint32_t i;
259
260         for (i = 0; i < app->n_pktq_source; i++) {
261                 struct app_pktq_source_params *p = &app->source_params[i];
262                 uint32_t n_readers = app_source_get_readers(app, p);
263
264                 APP_CHECK((n_readers != 0),
265                         "%s has no reader\n", p->name);
266
267                 APP_CHECK((n_readers == 1),
268                         "%s has more than one reader\n", p->name);
269         }
270 }
271
272 static void
273 check_sinks(struct app_params *app)
274 {
275         uint32_t i;
276
277         for (i = 0; i < app->n_pktq_sink; i++) {
278                 struct app_pktq_sink_params *p = &app->sink_params[i];
279                 uint32_t n_writers = app_sink_get_writers(app, p);
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_msgqs(struct app_params *app)
291 {
292         uint32_t i;
293
294         for (i = 0; i < app->n_msgq; i++) {
295                 struct app_msgq_params *p = &app->msgq_params[i];
296                 uint32_t n_readers = app_msgq_get_readers(app, p);
297                 uint32_t n_writers = app_msgq_get_writers(app, p);
298                 uint32_t msgq_req_pipeline, msgq_rsp_pipeline;
299                 uint32_t msgq_req_core, msgq_rsp_core;
300
301                 APP_CHECK((p->size > 0),
302                         "%s size is 0\n", p->name);
303
304                 APP_CHECK((rte_is_power_of_2(p->size)),
305                         "%s size is not a power of 2\n", p->name);
306
307                 msgq_req_pipeline = (strncmp(p->name, "MSGQ-REQ-PIPELINE",
308                         strlen("MSGQ-REQ-PIPELINE")) == 0);
309
310                 msgq_rsp_pipeline = (strncmp(p->name, "MSGQ-RSP-PIPELINE",
311                         strlen("MSGQ-RSP-PIPELINE")) == 0);
312
313                 msgq_req_core = (strncmp(p->name, "MSGQ-REQ-CORE",
314                         strlen("MSGQ-REQ-CORE")) == 0);
315
316                 msgq_rsp_core = (strncmp(p->name, "MSGQ-RSP-CORE",
317                         strlen("MSGQ-RSP-CORE")) == 0);
318
319                 if ((msgq_req_pipeline == 0) &&
320                         (msgq_rsp_pipeline == 0) &&
321                         (msgq_req_core == 0) &&
322                         (msgq_rsp_core == 0)) {
323                         APP_CHECK((n_readers != 0),
324                                 "%s has no reader\n", p->name);
325
326                         APP_CHECK((n_readers == 1),
327                                 "%s has more than one reader\n", p->name);
328
329                         APP_CHECK((n_writers != 0),
330                                 "%s has no writer\n", p->name);
331
332                         APP_CHECK((n_writers == 1),
333                                 "%s has more than one writer\n", p->name);
334                 }
335
336                 if (msgq_req_pipeline) {
337                         struct app_pipeline_params *pipeline;
338                         uint32_t pipeline_id;
339
340                         APP_PARAM_GET_ID(p, "MSGQ-REQ-PIPELINE", pipeline_id);
341
342                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
343                                 "PIPELINE",
344                                 pipeline_id,
345                                 pipeline);
346
347                         APP_CHECK((pipeline != NULL),
348                                 "%s is not associated with a valid pipeline\n",
349                                 p->name);
350                 }
351
352                 if (msgq_rsp_pipeline) {
353                         struct app_pipeline_params *pipeline;
354                         uint32_t pipeline_id;
355
356                         APP_PARAM_GET_ID(p, "MSGQ-RSP-PIPELINE", pipeline_id);
357
358                         APP_PARAM_FIND_BY_ID(app->pipeline_params,
359                                 "PIPELINE",
360                                 pipeline_id,
361                                 pipeline);
362
363                         APP_CHECK((pipeline != NULL),
364                                 "%s is not associated with a valid pipeline\n",
365                                 p->name);
366                 }
367         }
368 }
369
370 static void
371 check_pipelines(struct app_params *app)
372 {
373         uint32_t i;
374
375         for (i = 0; i < app->n_pipelines; i++) {
376                 struct app_pipeline_params *p = &app->pipeline_params[i];
377
378                 APP_CHECK((p->n_msgq_in == p->n_msgq_out),
379                         "%s number of input MSGQs does not match "
380                         "the number of output MSGQs\n", p->name);
381         }
382 }
383
384 int
385 app_config_check(struct app_params *app)
386 {
387         check_mempools(app);
388         check_links(app);
389         check_rxqs(app);
390         check_txqs(app);
391         check_swqs(app);
392         check_tms(app);
393         check_sources(app);
394         check_sinks(app);
395         check_msgqs(app);
396         check_pipelines(app);
397
398         return 0;
399 }