]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/examples/ip_pipeline/config_check.c
update download target update for octopus release
[ceph.git] / ceph / src / seastar / dpdk / 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_taps(struct app_params *app)
320 {
321 uint32_t i;
322
323 for (i = 0; i < app->n_pktq_tap; i++) {
324 struct app_pktq_tap_params *p = &app->tap_params[i];
325 uint32_t n_readers = app_tap_get_readers(app, p);
326 uint32_t n_writers = app_tap_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 APP_CHECK((p->burst_read > 0),
341 "%s read burst size is 0\n", p->name);
342
343 APP_CHECK((p->burst_write > 0),
344 "%s write burst size is 0\n", p->name);
345 }
346 }
347
348 static void
349 check_knis(struct app_params *app) {
350 uint32_t i;
351
352 for (i = 0; i < app->n_pktq_kni; i++) {
353 struct app_pktq_kni_params *p = &app->kni_params[i];
354 uint32_t n_readers = app_kni_get_readers(app, p);
355 uint32_t n_writers = app_kni_get_writers(app, p);
356
357 APP_CHECK((n_readers != 0),
358 "%s has no reader\n", p->name);
359
360 APP_CHECK((n_readers == 1),
361 "%s has more than one reader\n", p->name);
362
363 APP_CHECK((n_writers != 0),
364 "%s has no writer\n", p->name);
365
366 APP_CHECK((n_writers == 1),
367 "%s has more than one writer\n", p->name);
368 }
369 }
370
371 static void
372 check_sources(struct app_params *app)
373 {
374 uint32_t i;
375
376 for (i = 0; i < app->n_pktq_source; i++) {
377 struct app_pktq_source_params *p = &app->source_params[i];
378 uint32_t n_readers = app_source_get_readers(app, p);
379
380 APP_CHECK((n_readers != 0),
381 "%s has no reader\n", p->name);
382
383 APP_CHECK((n_readers == 1),
384 "%s has more than one reader\n", p->name);
385 }
386 }
387
388 static void
389 check_sinks(struct app_params *app)
390 {
391 uint32_t i;
392
393 for (i = 0; i < app->n_pktq_sink; i++) {
394 struct app_pktq_sink_params *p = &app->sink_params[i];
395 uint32_t n_writers = app_sink_get_writers(app, p);
396
397 APP_CHECK((n_writers != 0),
398 "%s has no writer\n", p->name);
399
400 APP_CHECK((n_writers == 1),
401 "%s has more than one writer\n", p->name);
402 }
403 }
404
405 static void
406 check_msgqs(struct app_params *app)
407 {
408 uint32_t i;
409
410 for (i = 0; i < app->n_msgq; i++) {
411 struct app_msgq_params *p = &app->msgq_params[i];
412 uint32_t n_readers = app_msgq_get_readers(app, p);
413 uint32_t n_writers = app_msgq_get_writers(app, p);
414 uint32_t msgq_req_pipeline, msgq_rsp_pipeline;
415 uint32_t msgq_req_core, msgq_rsp_core;
416
417 APP_CHECK((p->size > 0),
418 "%s size is 0\n", p->name);
419
420 APP_CHECK((rte_is_power_of_2(p->size)),
421 "%s size is not a power of 2\n", p->name);
422
423 msgq_req_pipeline = (strncmp(p->name, "MSGQ-REQ-PIPELINE",
424 strlen("MSGQ-REQ-PIPELINE")) == 0);
425
426 msgq_rsp_pipeline = (strncmp(p->name, "MSGQ-RSP-PIPELINE",
427 strlen("MSGQ-RSP-PIPELINE")) == 0);
428
429 msgq_req_core = (strncmp(p->name, "MSGQ-REQ-CORE",
430 strlen("MSGQ-REQ-CORE")) == 0);
431
432 msgq_rsp_core = (strncmp(p->name, "MSGQ-RSP-CORE",
433 strlen("MSGQ-RSP-CORE")) == 0);
434
435 if ((msgq_req_pipeline == 0) &&
436 (msgq_rsp_pipeline == 0) &&
437 (msgq_req_core == 0) &&
438 (msgq_rsp_core == 0)) {
439 APP_CHECK((n_readers != 0),
440 "%s has no reader\n", p->name);
441
442 APP_CHECK((n_readers == 1),
443 "%s has more than one reader\n", p->name);
444
445 APP_CHECK((n_writers != 0),
446 "%s has no writer\n", p->name);
447
448 APP_CHECK((n_writers == 1),
449 "%s has more than one writer\n", p->name);
450 }
451
452 if (msgq_req_pipeline) {
453 struct app_pipeline_params *pipeline;
454 uint32_t pipeline_id;
455
456 APP_PARAM_GET_ID(p, "MSGQ-REQ-PIPELINE", pipeline_id);
457
458 APP_PARAM_FIND_BY_ID(app->pipeline_params,
459 "PIPELINE",
460 pipeline_id,
461 pipeline);
462
463 APP_CHECK((pipeline != NULL),
464 "%s is not associated with a valid pipeline\n",
465 p->name);
466 }
467
468 if (msgq_rsp_pipeline) {
469 struct app_pipeline_params *pipeline;
470 uint32_t pipeline_id;
471
472 APP_PARAM_GET_ID(p, "MSGQ-RSP-PIPELINE", pipeline_id);
473
474 APP_PARAM_FIND_BY_ID(app->pipeline_params,
475 "PIPELINE",
476 pipeline_id,
477 pipeline);
478
479 APP_CHECK((pipeline != NULL),
480 "%s is not associated with a valid pipeline\n",
481 p->name);
482 }
483 }
484 }
485
486 static void
487 check_pipelines(struct app_params *app)
488 {
489 uint32_t i;
490
491 for (i = 0; i < app->n_pipelines; i++) {
492 struct app_pipeline_params *p = &app->pipeline_params[i];
493
494 APP_CHECK((p->n_msgq_in == p->n_msgq_out),
495 "%s number of input MSGQs does not match "
496 "the number of output MSGQs\n", p->name);
497 }
498 }
499
500 int
501 app_config_check(struct app_params *app)
502 {
503 check_mempools(app);
504 check_links(app);
505 check_rxqs(app);
506 check_txqs(app);
507 check_swqs(app);
508 check_tms(app);
509 check_taps(app);
510 check_knis(app);
511 check_sources(app);
512 check_sinks(app);
513 check_msgqs(app);
514 check_pipelines(app);
515
516 return 0;
517 }