]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | #ifndef __INCLUDE_APP_H__ | |
35 | #define __INCLUDE_APP_H__ | |
36 | ||
37 | #include <stdint.h> | |
38 | #include <string.h> | |
39 | ||
40 | #include <rte_common.h> | |
41 | #include <rte_mempool.h> | |
42 | #include <rte_ring.h> | |
43 | #include <rte_sched.h> | |
44 | #include <cmdline_parse.h> | |
45 | ||
46 | #include <rte_ethdev.h> | |
47 | #ifdef RTE_LIBRTE_KNI | |
48 | #include <rte_kni.h> | |
49 | #endif | |
50 | ||
51 | #include "cpu_core_map.h" | |
52 | #include "pipeline.h" | |
53 | ||
54 | #define APP_PARAM_NAME_SIZE PIPELINE_NAME_SIZE | |
55 | #define APP_LINK_PCI_BDF_SIZE 16 | |
56 | ||
57 | #ifndef APP_LINK_MAX_HWQ_IN | |
58 | #define APP_LINK_MAX_HWQ_IN 128 | |
59 | #endif | |
60 | ||
61 | #ifndef APP_LINK_MAX_HWQ_OUT | |
62 | #define APP_LINK_MAX_HWQ_OUT 128 | |
63 | #endif | |
64 | ||
65 | struct app_mempool_params { | |
66 | char *name; | |
67 | uint32_t parsed; | |
68 | uint32_t buffer_size; | |
69 | uint32_t pool_size; | |
70 | uint32_t cache_size; | |
71 | uint32_t cpu_socket_id; | |
72 | }; | |
73 | ||
74 | struct app_link_params { | |
75 | char *name; | |
76 | uint32_t parsed; | |
77 | uint32_t pmd_id; /* Generated based on port mask */ | |
78 | uint32_t arp_q; /* 0 = Disabled (packets go to default queue 0) */ | |
79 | uint32_t tcp_syn_q; /* 0 = Disabled (pkts go to default queue) */ | |
80 | uint32_t ip_local_q; /* 0 = Disabled (pkts go to default queue 0) */ | |
81 | uint32_t tcp_local_q; /* 0 = Disabled (pkts go to default queue 0) */ | |
82 | uint32_t udp_local_q; /* 0 = Disabled (pkts go to default queue 0) */ | |
83 | uint32_t sctp_local_q; /* 0 = Disabled (pkts go to default queue 0) */ | |
84 | uint32_t rss_qs[APP_LINK_MAX_HWQ_IN]; | |
85 | uint32_t n_rss_qs; | |
86 | uint64_t rss_proto_ipv4; | |
87 | uint64_t rss_proto_ipv6; | |
88 | uint64_t rss_proto_l2; | |
89 | uint32_t promisc; | |
90 | uint32_t state; /* DOWN = 0, UP = 1 */ | |
91 | uint32_t ip; /* 0 = Invalid */ | |
92 | uint32_t depth; /* Valid only when IP is valid */ | |
93 | uint64_t mac_addr; /* Read from HW */ | |
94 | char pci_bdf[APP_LINK_PCI_BDF_SIZE]; | |
95 | ||
96 | struct rte_eth_conf conf; | |
97 | }; | |
98 | ||
99 | struct app_pktq_hwq_in_params { | |
100 | char *name; | |
101 | uint32_t parsed; | |
102 | uint32_t mempool_id; /* Position in the app->mempool_params */ | |
103 | uint32_t size; | |
104 | uint32_t burst; | |
105 | ||
106 | struct rte_eth_rxconf conf; | |
107 | }; | |
108 | ||
109 | struct app_pktq_hwq_out_params { | |
110 | char *name; | |
111 | uint32_t parsed; | |
112 | uint32_t size; | |
113 | uint32_t burst; | |
114 | uint32_t dropless; | |
115 | uint64_t n_retries; | |
116 | struct rte_eth_txconf conf; | |
117 | }; | |
118 | ||
119 | struct app_pktq_swq_params { | |
120 | char *name; | |
121 | uint32_t parsed; | |
122 | uint32_t size; | |
123 | uint32_t burst_read; | |
124 | uint32_t burst_write; | |
125 | uint32_t dropless; | |
126 | uint64_t n_retries; | |
127 | uint32_t cpu_socket_id; | |
128 | uint32_t ipv4_frag; | |
129 | uint32_t ipv6_frag; | |
130 | uint32_t ipv4_ras; | |
131 | uint32_t ipv6_ras; | |
132 | uint32_t mtu; | |
133 | uint32_t metadata_size; | |
134 | uint32_t mempool_direct_id; | |
135 | uint32_t mempool_indirect_id; | |
136 | }; | |
137 | ||
138 | struct app_pktq_kni_params { | |
139 | char *name; | |
140 | uint32_t parsed; | |
141 | ||
142 | uint32_t socket_id; | |
143 | uint32_t core_id; | |
144 | uint32_t hyper_th_id; | |
145 | uint32_t force_bind; | |
146 | ||
147 | uint32_t mempool_id; /* Position in the app->mempool_params */ | |
148 | uint32_t burst_read; | |
149 | uint32_t burst_write; | |
150 | uint32_t dropless; | |
151 | uint64_t n_retries; | |
152 | }; | |
153 | ||
154 | #ifndef APP_FILE_NAME_SIZE | |
155 | #define APP_FILE_NAME_SIZE 256 | |
156 | #endif | |
157 | ||
158 | #ifndef APP_MAX_SCHED_SUBPORTS | |
159 | #define APP_MAX_SCHED_SUBPORTS 8 | |
160 | #endif | |
161 | ||
162 | #ifndef APP_MAX_SCHED_PIPES | |
163 | #define APP_MAX_SCHED_PIPES 4096 | |
164 | #endif | |
165 | ||
166 | struct app_pktq_tm_params { | |
167 | char *name; | |
168 | uint32_t parsed; | |
169 | const char *file_name; | |
170 | struct rte_sched_port_params sched_port_params; | |
171 | struct rte_sched_subport_params | |
172 | sched_subport_params[APP_MAX_SCHED_SUBPORTS]; | |
173 | struct rte_sched_pipe_params | |
174 | sched_pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT]; | |
175 | int sched_pipe_to_profile[APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES]; | |
176 | uint32_t burst_read; | |
177 | uint32_t burst_write; | |
178 | }; | |
179 | ||
180 | struct app_pktq_tap_params { | |
181 | char *name; | |
182 | uint32_t parsed; | |
183 | uint32_t burst_read; | |
184 | uint32_t burst_write; | |
185 | uint32_t dropless; | |
186 | uint64_t n_retries; | |
187 | uint32_t mempool_id; /* Position in the app->mempool_params */ | |
188 | }; | |
189 | ||
190 | struct app_pktq_source_params { | |
191 | char *name; | |
192 | uint32_t parsed; | |
193 | uint32_t mempool_id; /* Position in the app->mempool_params array */ | |
194 | uint32_t burst; | |
195 | const char *file_name; /* Full path of PCAP file to be copied to mbufs */ | |
196 | uint32_t n_bytes_per_pkt; | |
197 | }; | |
198 | ||
199 | struct app_pktq_sink_params { | |
200 | char *name; | |
201 | uint8_t parsed; | |
202 | const char *file_name; /* Full path of PCAP file to be copied to mbufs */ | |
203 | uint32_t n_pkts_to_dump; | |
204 | }; | |
205 | ||
206 | struct app_msgq_params { | |
207 | char *name; | |
208 | uint32_t parsed; | |
209 | uint32_t size; | |
210 | uint32_t cpu_socket_id; | |
211 | }; | |
212 | ||
213 | enum app_pktq_in_type { | |
214 | APP_PKTQ_IN_HWQ, | |
215 | APP_PKTQ_IN_SWQ, | |
216 | APP_PKTQ_IN_TM, | |
217 | APP_PKTQ_IN_TAP, | |
218 | APP_PKTQ_IN_KNI, | |
219 | APP_PKTQ_IN_SOURCE, | |
220 | }; | |
221 | ||
222 | struct app_pktq_in_params { | |
223 | enum app_pktq_in_type type; | |
224 | uint32_t id; /* Position in the appropriate app array */ | |
225 | }; | |
226 | ||
227 | enum app_pktq_out_type { | |
228 | APP_PKTQ_OUT_HWQ, | |
229 | APP_PKTQ_OUT_SWQ, | |
230 | APP_PKTQ_OUT_TM, | |
231 | APP_PKTQ_OUT_TAP, | |
232 | APP_PKTQ_OUT_KNI, | |
233 | APP_PKTQ_OUT_SINK, | |
234 | }; | |
235 | ||
236 | struct app_pktq_out_params { | |
237 | enum app_pktq_out_type type; | |
238 | uint32_t id; /* Position in the appropriate app array */ | |
239 | }; | |
240 | ||
241 | #define APP_PIPELINE_TYPE_SIZE PIPELINE_TYPE_SIZE | |
242 | ||
243 | #define APP_MAX_PIPELINE_PKTQ_IN PIPELINE_MAX_PORT_IN | |
244 | #define APP_MAX_PIPELINE_PKTQ_OUT PIPELINE_MAX_PORT_OUT | |
245 | #define APP_MAX_PIPELINE_MSGQ_IN PIPELINE_MAX_MSGQ_IN | |
246 | #define APP_MAX_PIPELINE_MSGQ_OUT PIPELINE_MAX_MSGQ_OUT | |
247 | ||
248 | #define APP_MAX_PIPELINE_ARGS PIPELINE_MAX_ARGS | |
249 | ||
250 | struct app_pipeline_params { | |
251 | char *name; | |
252 | uint8_t parsed; | |
253 | ||
254 | char type[APP_PIPELINE_TYPE_SIZE]; | |
255 | ||
256 | uint32_t socket_id; | |
257 | uint32_t core_id; | |
258 | uint32_t hyper_th_id; | |
259 | ||
260 | struct app_pktq_in_params pktq_in[APP_MAX_PIPELINE_PKTQ_IN]; | |
261 | struct app_pktq_out_params pktq_out[APP_MAX_PIPELINE_PKTQ_OUT]; | |
262 | uint32_t msgq_in[APP_MAX_PIPELINE_MSGQ_IN]; | |
263 | uint32_t msgq_out[APP_MAX_PIPELINE_MSGQ_OUT]; | |
264 | ||
265 | uint32_t n_pktq_in; | |
266 | uint32_t n_pktq_out; | |
267 | uint32_t n_msgq_in; | |
268 | uint32_t n_msgq_out; | |
269 | ||
270 | uint32_t timer_period; | |
271 | ||
272 | char *args_name[APP_MAX_PIPELINE_ARGS]; | |
273 | char *args_value[APP_MAX_PIPELINE_ARGS]; | |
274 | uint32_t n_args; | |
275 | }; | |
276 | ||
277 | struct app_params; | |
278 | ||
279 | typedef void (*app_link_op)(struct app_params *app, | |
280 | uint32_t link_id, | |
281 | uint32_t up, | |
282 | void *arg); | |
283 | ||
284 | #ifndef APP_MAX_PIPELINES | |
285 | #define APP_MAX_PIPELINES 64 | |
286 | #endif | |
287 | ||
288 | struct app_link_data { | |
289 | app_link_op f_link[APP_MAX_PIPELINES]; | |
290 | void *arg[APP_MAX_PIPELINES]; | |
291 | }; | |
292 | ||
293 | struct app_pipeline_data { | |
294 | void *be; | |
295 | void *fe; | |
296 | struct pipeline_type *ptype; | |
297 | uint64_t timer_period; | |
298 | uint32_t enabled; | |
299 | }; | |
300 | ||
301 | struct app_thread_pipeline_data { | |
302 | uint32_t pipeline_id; | |
303 | void *be; | |
304 | pipeline_be_op_run f_run; | |
305 | pipeline_be_op_timer f_timer; | |
306 | uint64_t timer_period; | |
307 | uint64_t deadline; | |
308 | }; | |
309 | ||
310 | #ifndef APP_MAX_THREAD_PIPELINES | |
311 | #define APP_MAX_THREAD_PIPELINES 64 | |
312 | #endif | |
313 | ||
314 | #ifndef APP_THREAD_TIMER_PERIOD | |
315 | #define APP_THREAD_TIMER_PERIOD 1 | |
316 | #endif | |
317 | ||
318 | struct app_thread_data { | |
319 | struct app_thread_pipeline_data regular[APP_MAX_THREAD_PIPELINES]; | |
320 | struct app_thread_pipeline_data custom[APP_MAX_THREAD_PIPELINES]; | |
321 | ||
322 | uint32_t n_regular; | |
323 | uint32_t n_custom; | |
324 | ||
325 | uint64_t timer_period; | |
326 | uint64_t thread_req_deadline; | |
327 | ||
328 | uint64_t deadline; | |
329 | ||
330 | struct rte_ring *msgq_in; | |
331 | struct rte_ring *msgq_out; | |
332 | ||
333 | uint64_t headroom_time; | |
334 | uint64_t headroom_cycles; | |
335 | double headroom_ratio; | |
336 | } __rte_cache_aligned; | |
337 | ||
338 | #ifndef APP_MAX_LINKS | |
339 | #define APP_MAX_LINKS 16 | |
340 | #endif | |
341 | ||
342 | struct app_eal_params { | |
343 | /* Map lcore set to physical cpu set */ | |
344 | char *coremap; | |
345 | ||
346 | /* Core ID that is used as master */ | |
347 | uint32_t master_lcore_present; | |
348 | uint32_t master_lcore; | |
349 | ||
350 | /* Number of memory channels */ | |
351 | uint32_t channels_present; | |
352 | uint32_t channels; | |
353 | ||
354 | /* Memory to allocate (see also --socket-mem) */ | |
355 | uint32_t memory_present; | |
356 | uint32_t memory; | |
357 | ||
358 | /* Force number of memory ranks (don't detect) */ | |
359 | uint32_t ranks_present; | |
360 | uint32_t ranks; | |
361 | ||
362 | /* Add a PCI device in black list. */ | |
363 | char *pci_blacklist[APP_MAX_LINKS]; | |
364 | ||
365 | /* Add a PCI device in white list. */ | |
366 | char *pci_whitelist[APP_MAX_LINKS]; | |
367 | ||
368 | /* Add a virtual device. */ | |
369 | char *vdev[APP_MAX_LINKS]; | |
370 | ||
371 | /* Use VMware TSC map instead of native RDTSC */ | |
372 | uint32_t vmware_tsc_map_present; | |
373 | int vmware_tsc_map; | |
374 | ||
375 | /* Type of this process (primary|secondary|auto) */ | |
376 | char *proc_type; | |
377 | ||
378 | /* Set syslog facility */ | |
379 | char *syslog; | |
380 | ||
381 | /* Set default log level */ | |
382 | uint32_t log_level_present; | |
383 | uint32_t log_level; | |
384 | ||
385 | /* Display version information on startup */ | |
386 | uint32_t version_present; | |
387 | int version; | |
388 | ||
389 | /* This help */ | |
390 | uint32_t help_present; | |
391 | int help; | |
392 | ||
393 | /* Use malloc instead of hugetlbfs */ | |
394 | uint32_t no_huge_present; | |
395 | int no_huge; | |
396 | ||
397 | /* Disable PCI */ | |
398 | uint32_t no_pci_present; | |
399 | int no_pci; | |
400 | ||
401 | /* Disable HPET */ | |
402 | uint32_t no_hpet_present; | |
403 | int no_hpet; | |
404 | ||
405 | /* No shared config (mmap'd files) */ | |
406 | uint32_t no_shconf_present; | |
407 | int no_shconf; | |
408 | ||
409 | /* Add driver */ | |
410 | char *add_driver; | |
411 | ||
412 | /* Memory to allocate on sockets (comma separated values)*/ | |
413 | char *socket_mem; | |
414 | ||
415 | /* Directory where hugetlbfs is mounted */ | |
416 | char *huge_dir; | |
417 | ||
418 | /* Prefix for hugepage filenames */ | |
419 | char *file_prefix; | |
420 | ||
421 | /* Base virtual address */ | |
422 | char *base_virtaddr; | |
423 | ||
424 | /* Create /dev/uioX (usually done by hotplug) */ | |
425 | uint32_t create_uio_dev_present; | |
426 | int create_uio_dev; | |
427 | ||
428 | /* Interrupt mode for VFIO (legacy|msi|msix) */ | |
429 | char *vfio_intr; | |
430 | ||
431 | /* Support running on Xen dom0 without hugetlbfs */ | |
432 | uint32_t xen_dom0_present; | |
433 | int xen_dom0; | |
434 | ||
435 | uint32_t parsed; | |
436 | }; | |
437 | ||
438 | #ifndef APP_APPNAME_SIZE | |
439 | #define APP_APPNAME_SIZE 256 | |
440 | #endif | |
441 | ||
442 | #ifndef APP_MAX_MEMPOOLS | |
443 | #define APP_MAX_MEMPOOLS 8 | |
444 | #endif | |
445 | ||
446 | #define APP_MAX_HWQ_IN (APP_MAX_LINKS * APP_LINK_MAX_HWQ_IN) | |
447 | ||
448 | #define APP_MAX_HWQ_OUT (APP_MAX_LINKS * APP_LINK_MAX_HWQ_OUT) | |
449 | ||
450 | #ifndef APP_MAX_PKTQ_SWQ | |
451 | #define APP_MAX_PKTQ_SWQ 256 | |
452 | #endif | |
453 | ||
454 | #define APP_MAX_PKTQ_TM APP_MAX_LINKS | |
455 | ||
456 | #ifndef APP_MAX_PKTQ_TAP | |
457 | #define APP_MAX_PKTQ_TAP APP_MAX_LINKS | |
458 | #endif | |
459 | ||
460 | #define APP_MAX_PKTQ_KNI APP_MAX_LINKS | |
461 | ||
462 | #ifndef APP_MAX_PKTQ_SOURCE | |
463 | #define APP_MAX_PKTQ_SOURCE 64 | |
464 | #endif | |
465 | ||
466 | #ifndef APP_MAX_PKTQ_SINK | |
467 | #define APP_MAX_PKTQ_SINK 64 | |
468 | #endif | |
469 | ||
470 | #ifndef APP_MAX_MSGQ | |
471 | #define APP_MAX_MSGQ 256 | |
472 | #endif | |
473 | ||
474 | #ifndef APP_EAL_ARGC | |
475 | #define APP_EAL_ARGC 64 | |
476 | #endif | |
477 | ||
478 | #ifndef APP_MAX_PIPELINE_TYPES | |
479 | #define APP_MAX_PIPELINE_TYPES 64 | |
480 | #endif | |
481 | ||
482 | #ifndef APP_MAX_THREADS | |
483 | #define APP_MAX_THREADS RTE_MAX_LCORE | |
484 | #endif | |
485 | ||
486 | #ifndef APP_MAX_CMDS | |
487 | #define APP_MAX_CMDS 64 | |
488 | #endif | |
489 | ||
490 | #ifndef APP_THREAD_HEADROOM_STATS_COLLECT | |
491 | #define APP_THREAD_HEADROOM_STATS_COLLECT 1 | |
492 | #endif | |
493 | ||
11fdf7f2 TL |
494 | #define APP_CORE_MASK_SIZE \ |
495 | (RTE_MAX_LCORE / 64 + ((RTE_MAX_LCORE % 64) ? 1 : 0)) | |
496 | ||
7c673cae FG |
497 | struct app_params { |
498 | /* Config */ | |
499 | char app_name[APP_APPNAME_SIZE]; | |
500 | const char *config_file; | |
501 | const char *script_file; | |
502 | const char *parser_file; | |
503 | const char *output_file; | |
504 | const char *preproc; | |
505 | const char *preproc_args; | |
506 | uint64_t port_mask; | |
507 | uint32_t log_level; | |
508 | ||
509 | struct app_eal_params eal_params; | |
510 | struct app_mempool_params mempool_params[APP_MAX_MEMPOOLS]; | |
511 | struct app_link_params link_params[APP_MAX_LINKS]; | |
512 | struct app_pktq_hwq_in_params hwq_in_params[APP_MAX_HWQ_IN]; | |
513 | struct app_pktq_hwq_out_params hwq_out_params[APP_MAX_HWQ_OUT]; | |
514 | struct app_pktq_swq_params swq_params[APP_MAX_PKTQ_SWQ]; | |
515 | struct app_pktq_tm_params tm_params[APP_MAX_PKTQ_TM]; | |
516 | struct app_pktq_tap_params tap_params[APP_MAX_PKTQ_TAP]; | |
517 | struct app_pktq_kni_params kni_params[APP_MAX_PKTQ_KNI]; | |
518 | struct app_pktq_source_params source_params[APP_MAX_PKTQ_SOURCE]; | |
519 | struct app_pktq_sink_params sink_params[APP_MAX_PKTQ_SINK]; | |
520 | struct app_msgq_params msgq_params[APP_MAX_MSGQ]; | |
521 | struct app_pipeline_params pipeline_params[APP_MAX_PIPELINES]; | |
522 | ||
523 | uint32_t n_mempools; | |
524 | uint32_t n_links; | |
525 | uint32_t n_pktq_hwq_in; | |
526 | uint32_t n_pktq_hwq_out; | |
527 | uint32_t n_pktq_swq; | |
528 | uint32_t n_pktq_tm; | |
529 | uint32_t n_pktq_tap; | |
530 | uint32_t n_pktq_kni; | |
531 | uint32_t n_pktq_source; | |
532 | uint32_t n_pktq_sink; | |
533 | uint32_t n_msgq; | |
534 | uint32_t n_pipelines; | |
535 | ||
536 | /* Init */ | |
537 | char *eal_argv[1 + APP_EAL_ARGC]; | |
538 | struct cpu_core_map *core_map; | |
11fdf7f2 | 539 | uint64_t core_mask[APP_CORE_MASK_SIZE]; |
7c673cae FG |
540 | struct rte_mempool *mempool[APP_MAX_MEMPOOLS]; |
541 | struct app_link_data link_data[APP_MAX_LINKS]; | |
542 | struct rte_ring *swq[APP_MAX_PKTQ_SWQ]; | |
543 | struct rte_sched_port *tm[APP_MAX_PKTQ_TM]; | |
544 | int tap[APP_MAX_PKTQ_TAP]; | |
545 | #ifdef RTE_LIBRTE_KNI | |
546 | struct rte_kni *kni[APP_MAX_PKTQ_KNI]; | |
547 | #endif /* RTE_LIBRTE_KNI */ | |
548 | struct rte_ring *msgq[APP_MAX_MSGQ]; | |
549 | struct pipeline_type pipeline_type[APP_MAX_PIPELINE_TYPES]; | |
550 | struct app_pipeline_data pipeline_data[APP_MAX_PIPELINES]; | |
551 | struct app_thread_data thread_data[APP_MAX_THREADS]; | |
552 | cmdline_parse_ctx_t cmds[APP_MAX_CMDS + 1]; | |
553 | ||
554 | int eal_argc; | |
555 | uint32_t n_pipeline_types; | |
556 | uint32_t n_cmds; | |
557 | }; | |
558 | ||
559 | #define APP_PARAM_VALID(obj) ((obj)->name != NULL) | |
560 | ||
561 | #define APP_PARAM_COUNT(obj_array, n_objs) \ | |
562 | { \ | |
563 | size_t i; \ | |
564 | \ | |
565 | n_objs = 0; \ | |
566 | for (i = 0; i < RTE_DIM(obj_array); i++) \ | |
567 | if (APP_PARAM_VALID(&((obj_array)[i]))) \ | |
568 | n_objs++; \ | |
569 | } | |
570 | ||
571 | #define APP_PARAM_FIND(obj_array, key) \ | |
572 | ({ \ | |
573 | ssize_t obj_idx; \ | |
574 | const ssize_t obj_count = RTE_DIM(obj_array); \ | |
575 | \ | |
576 | for (obj_idx = 0; obj_idx < obj_count; obj_idx++) { \ | |
577 | if (!APP_PARAM_VALID(&((obj_array)[obj_idx]))) \ | |
578 | continue; \ | |
579 | \ | |
580 | if (strcmp(key, (obj_array)[obj_idx].name) == 0) \ | |
581 | break; \ | |
582 | } \ | |
583 | obj_idx < obj_count ? obj_idx : -ENOENT; \ | |
584 | }) | |
585 | ||
586 | #define APP_PARAM_FIND_BY_ID(obj_array, prefix, id, obj) \ | |
587 | do { \ | |
588 | char name[APP_PARAM_NAME_SIZE]; \ | |
589 | ssize_t pos; \ | |
590 | \ | |
591 | sprintf(name, prefix "%" PRIu32, id); \ | |
592 | pos = APP_PARAM_FIND(obj_array, name); \ | |
593 | obj = (pos < 0) ? NULL : &((obj_array)[pos]); \ | |
594 | } while (0) | |
595 | ||
596 | #define APP_PARAM_GET_ID(obj, prefix, id) \ | |
597 | do \ | |
598 | sscanf(obj->name, prefix "%" SCNu32, &id); \ | |
599 | while (0) \ | |
600 | ||
601 | #define APP_CHECK(exp, fmt, ...) \ | |
602 | do { \ | |
603 | if (!(exp)) { \ | |
604 | fprintf(stderr, fmt "\n", ## __VA_ARGS__); \ | |
605 | abort(); \ | |
606 | } \ | |
607 | } while (0) | |
608 | ||
609 | enum app_log_level { | |
610 | APP_LOG_LEVEL_HIGH = 1, | |
611 | APP_LOG_LEVEL_LOW, | |
612 | APP_LOG_LEVELS | |
613 | }; | |
614 | ||
615 | #define APP_LOG(app, level, fmt, ...) \ | |
616 | do { \ | |
617 | if (app->log_level >= APP_LOG_LEVEL_ ## level) \ | |
618 | fprintf(stdout, "[APP] " fmt "\n", ## __VA_ARGS__); \ | |
619 | } while (0) | |
620 | ||
621 | static inline uint32_t | |
622 | app_link_get_n_rxq(struct app_params *app, struct app_link_params *link) | |
623 | { | |
624 | uint32_t n_rxq = 0, link_id, i; | |
625 | uint32_t n_pktq_hwq_in = RTE_MIN(app->n_pktq_hwq_in, | |
626 | RTE_DIM(app->hwq_in_params)); | |
627 | ||
628 | APP_PARAM_GET_ID(link, "LINK", link_id); | |
629 | ||
630 | for (i = 0; i < n_pktq_hwq_in; i++) { | |
631 | struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i]; | |
632 | uint32_t rxq_link_id, rxq_queue_id; | |
633 | ||
634 | sscanf(p->name, "RXQ%" SCNu32 ".%" SCNu32, | |
635 | &rxq_link_id, &rxq_queue_id); | |
636 | if (rxq_link_id == link_id) | |
637 | n_rxq++; | |
638 | } | |
639 | ||
640 | return n_rxq; | |
641 | } | |
642 | ||
643 | static inline uint32_t | |
644 | app_link_get_n_txq(struct app_params *app, struct app_link_params *link) | |
645 | { | |
646 | uint32_t n_txq = 0, link_id, i; | |
647 | uint32_t n_pktq_hwq_out = RTE_MIN(app->n_pktq_hwq_out, | |
648 | RTE_DIM(app->hwq_out_params)); | |
649 | ||
650 | APP_PARAM_GET_ID(link, "LINK", link_id); | |
651 | ||
652 | for (i = 0; i < n_pktq_hwq_out; i++) { | |
653 | struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i]; | |
654 | uint32_t txq_link_id, txq_queue_id; | |
655 | ||
656 | sscanf(p->name, "TXQ%" SCNu32 ".%" SCNu32, | |
657 | &txq_link_id, &txq_queue_id); | |
658 | if (txq_link_id == link_id) | |
659 | n_txq++; | |
660 | } | |
661 | ||
662 | return n_txq; | |
663 | } | |
664 | ||
665 | static inline uint32_t | |
666 | app_rxq_get_readers(struct app_params *app, struct app_pktq_hwq_in_params *rxq) | |
667 | { | |
668 | uint32_t pos = rxq - app->hwq_in_params; | |
669 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
670 | RTE_DIM(app->pipeline_params)); | |
671 | uint32_t n_readers = 0, i; | |
672 | ||
673 | for (i = 0; i < n_pipelines; i++) { | |
674 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
675 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
676 | uint32_t j; | |
677 | ||
678 | for (j = 0; j < n_pktq_in; j++) { | |
679 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
680 | ||
681 | if ((pktq->type == APP_PKTQ_IN_HWQ) && | |
682 | (pktq->id == pos)) | |
683 | n_readers++; | |
684 | } | |
685 | } | |
686 | ||
687 | return n_readers; | |
688 | } | |
689 | ||
690 | static inline uint32_t | |
691 | app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq) | |
692 | { | |
693 | uint32_t pos = swq - app->swq_params; | |
694 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
695 | RTE_DIM(app->pipeline_params)); | |
696 | uint32_t n_readers = 0, i; | |
697 | ||
698 | for (i = 0; i < n_pipelines; i++) { | |
699 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
700 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
701 | uint32_t j; | |
702 | ||
703 | for (j = 0; j < n_pktq_in; j++) { | |
704 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
705 | ||
706 | if ((pktq->type == APP_PKTQ_IN_SWQ) && | |
707 | (pktq->id == pos)) | |
708 | n_readers++; | |
709 | } | |
710 | } | |
711 | ||
712 | return n_readers; | |
713 | } | |
714 | ||
715 | static inline struct app_pipeline_params * | |
716 | app_swq_get_reader(struct app_params *app, | |
717 | struct app_pktq_swq_params *swq, | |
718 | uint32_t *pktq_in_id) | |
719 | { | |
720 | struct app_pipeline_params *reader = NULL; | |
721 | uint32_t pos = swq - app->swq_params; | |
722 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
723 | RTE_DIM(app->pipeline_params)); | |
724 | uint32_t n_readers = 0, id = 0, i; | |
725 | ||
726 | for (i = 0; i < n_pipelines; i++) { | |
727 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
728 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
729 | uint32_t j; | |
730 | ||
731 | for (j = 0; j < n_pktq_in; j++) { | |
732 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
733 | ||
734 | if ((pktq->type == APP_PKTQ_IN_SWQ) && | |
735 | (pktq->id == pos)) { | |
736 | n_readers++; | |
737 | reader = p; | |
738 | id = j; | |
739 | } | |
740 | } | |
741 | } | |
742 | ||
743 | if (n_readers != 1) | |
744 | return NULL; | |
745 | ||
746 | *pktq_in_id = id; | |
747 | return reader; | |
748 | } | |
749 | ||
750 | static inline uint32_t | |
751 | app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm) | |
752 | { | |
753 | uint32_t pos = tm - app->tm_params; | |
754 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
755 | RTE_DIM(app->pipeline_params)); | |
756 | uint32_t n_readers = 0, i; | |
757 | ||
758 | for (i = 0; i < n_pipelines; i++) { | |
759 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
760 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
761 | uint32_t j; | |
762 | ||
763 | for (j = 0; j < n_pktq_in; j++) { | |
764 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
765 | ||
766 | if ((pktq->type == APP_PKTQ_IN_TM) && | |
767 | (pktq->id == pos)) | |
768 | n_readers++; | |
769 | } | |
770 | } | |
771 | ||
772 | return n_readers; | |
773 | } | |
774 | ||
775 | static inline struct app_pipeline_params * | |
776 | app_tm_get_reader(struct app_params *app, | |
777 | struct app_pktq_tm_params *tm, | |
778 | uint32_t *pktq_in_id) | |
779 | { | |
780 | struct app_pipeline_params *reader = NULL; | |
781 | uint32_t pos = tm - app->tm_params; | |
782 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
783 | RTE_DIM(app->pipeline_params)); | |
784 | uint32_t n_readers = 0, id = 0, i; | |
785 | ||
786 | for (i = 0; i < n_pipelines; i++) { | |
787 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
788 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
789 | uint32_t j; | |
790 | ||
791 | for (j = 0; j < n_pktq_in; j++) { | |
792 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
793 | ||
794 | if ((pktq->type == APP_PKTQ_IN_TM) && | |
795 | (pktq->id == pos)) { | |
796 | n_readers++; | |
797 | reader = p; | |
798 | id = j; | |
799 | } | |
800 | } | |
801 | } | |
802 | ||
803 | if (n_readers != 1) | |
804 | return NULL; | |
805 | ||
806 | *pktq_in_id = id; | |
807 | return reader; | |
808 | } | |
809 | ||
810 | static inline uint32_t | |
811 | app_tap_get_readers(struct app_params *app, struct app_pktq_tap_params *tap) | |
812 | { | |
813 | uint32_t pos = tap - app->tap_params; | |
814 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
815 | RTE_DIM(app->pipeline_params)); | |
816 | uint32_t n_readers = 0, i; | |
817 | ||
818 | for (i = 0; i < n_pipelines; i++) { | |
819 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
820 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
821 | uint32_t j; | |
822 | ||
823 | for (j = 0; j < n_pktq_in; j++) { | |
824 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
825 | ||
826 | if ((pktq->type == APP_PKTQ_IN_TAP) && | |
827 | (pktq->id == pos)) | |
828 | n_readers++; | |
829 | } | |
830 | } | |
831 | ||
832 | return n_readers; | |
833 | } | |
834 | ||
835 | static inline struct app_pipeline_params * | |
836 | app_tap_get_reader(struct app_params *app, | |
837 | struct app_pktq_tap_params *tap, | |
838 | uint32_t *pktq_in_id) | |
839 | { | |
840 | struct app_pipeline_params *reader = NULL; | |
841 | uint32_t pos = tap - app->tap_params; | |
842 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
843 | RTE_DIM(app->pipeline_params)); | |
844 | uint32_t n_readers = 0, id = 0, i; | |
845 | ||
846 | for (i = 0; i < n_pipelines; i++) { | |
847 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
848 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
849 | uint32_t j; | |
850 | ||
851 | for (j = 0; j < n_pktq_in; j++) { | |
852 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
853 | ||
854 | if ((pktq->type == APP_PKTQ_IN_TAP) && | |
855 | (pktq->id == pos)) { | |
856 | n_readers++; | |
857 | reader = p; | |
858 | id = j; | |
859 | } | |
860 | } | |
861 | } | |
862 | ||
863 | if (n_readers != 1) | |
864 | return NULL; | |
865 | ||
866 | *pktq_in_id = id; | |
867 | return reader; | |
868 | } | |
869 | ||
870 | static inline uint32_t | |
871 | app_kni_get_readers(struct app_params *app, struct app_pktq_kni_params *kni) | |
872 | { | |
873 | uint32_t pos = kni - app->kni_params; | |
874 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
875 | RTE_DIM(app->pipeline_params)); | |
876 | uint32_t n_readers = 0, i; | |
877 | ||
878 | for (i = 0; i < n_pipelines; i++) { | |
879 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
880 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
881 | uint32_t j; | |
882 | ||
883 | for (j = 0; j < n_pktq_in; j++) { | |
884 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
885 | ||
886 | if ((pktq->type == APP_PKTQ_IN_KNI) && | |
887 | (pktq->id == pos)) | |
888 | n_readers++; | |
889 | } | |
890 | } | |
891 | ||
892 | return n_readers; | |
893 | } | |
894 | ||
895 | static inline struct app_pipeline_params * | |
896 | app_kni_get_reader(struct app_params *app, | |
897 | struct app_pktq_kni_params *kni, | |
898 | uint32_t *pktq_in_id) | |
899 | { | |
900 | struct app_pipeline_params *reader = NULL; | |
901 | uint32_t pos = kni - app->kni_params; | |
902 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
903 | RTE_DIM(app->pipeline_params)); | |
904 | uint32_t n_readers = 0, id = 0, i; | |
905 | ||
906 | for (i = 0; i < n_pipelines; i++) { | |
907 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
908 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
909 | uint32_t j; | |
910 | ||
911 | for (j = 0; j < n_pktq_in; j++) { | |
912 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
913 | ||
914 | if ((pktq->type == APP_PKTQ_IN_KNI) && | |
915 | (pktq->id == pos)) { | |
916 | n_readers++; | |
917 | reader = p; | |
918 | id = j; | |
919 | } | |
920 | } | |
921 | } | |
922 | ||
923 | if (n_readers != 1) | |
924 | return NULL; | |
925 | ||
926 | *pktq_in_id = id; | |
927 | return reader; | |
928 | } | |
929 | ||
930 | static inline uint32_t | |
931 | app_source_get_readers(struct app_params *app, | |
932 | struct app_pktq_source_params *source) | |
933 | { | |
934 | uint32_t pos = source - app->source_params; | |
935 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
936 | RTE_DIM(app->pipeline_params)); | |
937 | uint32_t n_readers = 0, i; | |
938 | ||
939 | for (i = 0; i < n_pipelines; i++) { | |
940 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
941 | uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in)); | |
942 | uint32_t j; | |
943 | ||
944 | for (j = 0; j < n_pktq_in; j++) { | |
945 | struct app_pktq_in_params *pktq = &p->pktq_in[j]; | |
946 | ||
947 | if ((pktq->type == APP_PKTQ_IN_SOURCE) && | |
948 | (pktq->id == pos)) | |
949 | n_readers++; | |
950 | } | |
951 | } | |
952 | ||
953 | return n_readers; | |
954 | } | |
955 | ||
956 | static inline uint32_t | |
957 | app_msgq_get_readers(struct app_params *app, struct app_msgq_params *msgq) | |
958 | { | |
959 | uint32_t pos = msgq - app->msgq_params; | |
960 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
961 | RTE_DIM(app->pipeline_params)); | |
962 | uint32_t n_readers = 0, i; | |
963 | ||
964 | for (i = 0; i < n_pipelines; i++) { | |
965 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
966 | uint32_t n_msgq_in = RTE_MIN(p->n_msgq_in, RTE_DIM(p->msgq_in)); | |
967 | uint32_t j; | |
968 | ||
969 | for (j = 0; j < n_msgq_in; j++) | |
970 | if (p->msgq_in[j] == pos) | |
971 | n_readers++; | |
972 | } | |
973 | ||
974 | return n_readers; | |
975 | } | |
976 | ||
977 | static inline uint32_t | |
978 | app_txq_get_writers(struct app_params *app, struct app_pktq_hwq_out_params *txq) | |
979 | { | |
980 | uint32_t pos = txq - app->hwq_out_params; | |
981 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
982 | RTE_DIM(app->pipeline_params)); | |
983 | uint32_t n_writers = 0, i; | |
984 | ||
985 | for (i = 0; i < n_pipelines; i++) { | |
986 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
987 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
988 | RTE_DIM(p->pktq_out)); | |
989 | uint32_t j; | |
990 | ||
991 | for (j = 0; j < n_pktq_out; j++) { | |
992 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
993 | ||
994 | if ((pktq->type == APP_PKTQ_OUT_HWQ) && | |
995 | (pktq->id == pos)) | |
996 | n_writers++; | |
997 | } | |
998 | } | |
999 | ||
1000 | return n_writers; | |
1001 | } | |
1002 | ||
1003 | static inline uint32_t | |
1004 | app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq) | |
1005 | { | |
1006 | uint32_t pos = swq - app->swq_params; | |
1007 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1008 | RTE_DIM(app->pipeline_params)); | |
1009 | uint32_t n_writers = 0, i; | |
1010 | ||
1011 | for (i = 0; i < n_pipelines; i++) { | |
1012 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1013 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1014 | RTE_DIM(p->pktq_out)); | |
1015 | uint32_t j; | |
1016 | ||
1017 | for (j = 0; j < n_pktq_out; j++) { | |
1018 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1019 | ||
1020 | if ((pktq->type == APP_PKTQ_OUT_SWQ) && | |
1021 | (pktq->id == pos)) | |
1022 | n_writers++; | |
1023 | } | |
1024 | } | |
1025 | ||
1026 | return n_writers; | |
1027 | } | |
1028 | ||
1029 | static inline struct app_pipeline_params * | |
1030 | app_swq_get_writer(struct app_params *app, | |
1031 | struct app_pktq_swq_params *swq, | |
1032 | uint32_t *pktq_out_id) | |
1033 | { | |
1034 | struct app_pipeline_params *writer = NULL; | |
1035 | uint32_t pos = swq - app->swq_params; | |
1036 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1037 | RTE_DIM(app->pipeline_params)); | |
1038 | uint32_t n_writers = 0, id = 0, i; | |
1039 | ||
1040 | for (i = 0; i < n_pipelines; i++) { | |
1041 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1042 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1043 | RTE_DIM(p->pktq_out)); | |
1044 | uint32_t j; | |
1045 | ||
1046 | for (j = 0; j < n_pktq_out; j++) { | |
1047 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1048 | ||
1049 | if ((pktq->type == APP_PKTQ_OUT_SWQ) && | |
1050 | (pktq->id == pos)) { | |
1051 | n_writers++; | |
1052 | writer = p; | |
1053 | id = j; | |
1054 | } | |
1055 | } | |
1056 | } | |
1057 | ||
1058 | if (n_writers != 1) | |
1059 | return NULL; | |
1060 | ||
1061 | *pktq_out_id = id; | |
1062 | return writer; | |
1063 | } | |
1064 | ||
1065 | static inline uint32_t | |
1066 | app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm) | |
1067 | { | |
1068 | uint32_t pos = tm - app->tm_params; | |
1069 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1070 | RTE_DIM(app->pipeline_params)); | |
1071 | uint32_t n_writers = 0, i; | |
1072 | ||
1073 | for (i = 0; i < n_pipelines; i++) { | |
1074 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1075 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1076 | RTE_DIM(p->pktq_out)); | |
1077 | uint32_t j; | |
1078 | ||
1079 | for (j = 0; j < n_pktq_out; j++) { | |
1080 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1081 | ||
1082 | if ((pktq->type == APP_PKTQ_OUT_TM) && | |
1083 | (pktq->id == pos)) | |
1084 | n_writers++; | |
1085 | } | |
1086 | } | |
1087 | ||
1088 | return n_writers; | |
1089 | } | |
1090 | ||
1091 | static inline struct app_pipeline_params * | |
1092 | app_tm_get_writer(struct app_params *app, | |
1093 | struct app_pktq_tm_params *tm, | |
1094 | uint32_t *pktq_out_id) | |
1095 | { | |
1096 | struct app_pipeline_params *writer = NULL; | |
1097 | uint32_t pos = tm - app->tm_params; | |
1098 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1099 | RTE_DIM(app->pipeline_params)); | |
1100 | uint32_t n_writers = 0, id = 0, i; | |
1101 | ||
1102 | for (i = 0; i < n_pipelines; i++) { | |
1103 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1104 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1105 | RTE_DIM(p->pktq_out)); | |
1106 | uint32_t j; | |
1107 | ||
1108 | for (j = 0; j < n_pktq_out; j++) { | |
1109 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1110 | ||
1111 | if ((pktq->type == APP_PKTQ_OUT_TM) && | |
1112 | (pktq->id == pos)) { | |
1113 | n_writers++; | |
1114 | writer = p; | |
1115 | id = j; | |
1116 | } | |
1117 | } | |
1118 | } | |
1119 | ||
1120 | if (n_writers != 1) | |
1121 | return NULL; | |
1122 | ||
1123 | *pktq_out_id = id; | |
1124 | return writer; | |
1125 | } | |
1126 | ||
1127 | static inline uint32_t | |
1128 | app_tap_get_writers(struct app_params *app, struct app_pktq_tap_params *tap) | |
1129 | { | |
1130 | uint32_t pos = tap - app->tap_params; | |
1131 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1132 | RTE_DIM(app->pipeline_params)); | |
1133 | uint32_t n_writers = 0, i; | |
1134 | ||
1135 | for (i = 0; i < n_pipelines; i++) { | |
1136 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1137 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1138 | RTE_DIM(p->pktq_out)); | |
1139 | uint32_t j; | |
1140 | ||
1141 | for (j = 0; j < n_pktq_out; j++) { | |
1142 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1143 | ||
1144 | if ((pktq->type == APP_PKTQ_OUT_TAP) && | |
1145 | (pktq->id == pos)) | |
1146 | n_writers++; | |
1147 | } | |
1148 | } | |
1149 | ||
1150 | return n_writers; | |
1151 | } | |
1152 | ||
1153 | static inline struct app_pipeline_params * | |
1154 | app_tap_get_writer(struct app_params *app, | |
1155 | struct app_pktq_tap_params *tap, | |
1156 | uint32_t *pktq_out_id) | |
1157 | { | |
1158 | struct app_pipeline_params *writer = NULL; | |
1159 | uint32_t pos = tap - app->tap_params; | |
1160 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1161 | RTE_DIM(app->pipeline_params)); | |
1162 | uint32_t n_writers = 0, id = 0, i; | |
1163 | ||
1164 | for (i = 0; i < n_pipelines; i++) { | |
1165 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1166 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1167 | RTE_DIM(p->pktq_out)); | |
1168 | uint32_t j; | |
1169 | ||
1170 | for (j = 0; j < n_pktq_out; j++) { | |
1171 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1172 | ||
1173 | if ((pktq->type == APP_PKTQ_OUT_TAP) && | |
1174 | (pktq->id == pos)) { | |
1175 | n_writers++; | |
1176 | writer = p; | |
1177 | id = j; | |
1178 | } | |
1179 | } | |
1180 | } | |
1181 | ||
1182 | if (n_writers != 1) | |
1183 | return NULL; | |
1184 | ||
1185 | *pktq_out_id = id; | |
1186 | return writer; | |
1187 | } | |
1188 | ||
1189 | static inline uint32_t | |
1190 | app_kni_get_writers(struct app_params *app, struct app_pktq_kni_params *kni) | |
1191 | { | |
1192 | uint32_t pos = kni - app->kni_params; | |
1193 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1194 | RTE_DIM(app->pipeline_params)); | |
1195 | uint32_t n_writers = 0, i; | |
1196 | ||
1197 | for (i = 0; i < n_pipelines; i++) { | |
1198 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1199 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1200 | RTE_DIM(p->pktq_out)); | |
1201 | uint32_t j; | |
1202 | ||
1203 | for (j = 0; j < n_pktq_out; j++) { | |
1204 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1205 | ||
1206 | if ((pktq->type == APP_PKTQ_OUT_KNI) && | |
1207 | (pktq->id == pos)) | |
1208 | n_writers++; | |
1209 | } | |
1210 | } | |
1211 | ||
1212 | return n_writers; | |
1213 | } | |
1214 | ||
1215 | static inline struct app_pipeline_params * | |
1216 | app_kni_get_writer(struct app_params *app, | |
1217 | struct app_pktq_kni_params *kni, | |
1218 | uint32_t *pktq_out_id) | |
1219 | { | |
1220 | struct app_pipeline_params *writer = NULL; | |
1221 | uint32_t pos = kni - app->kni_params; | |
1222 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1223 | RTE_DIM(app->pipeline_params)); | |
1224 | uint32_t n_writers = 0, id = 0, i; | |
1225 | ||
1226 | for (i = 0; i < n_pipelines; i++) { | |
1227 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1228 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1229 | RTE_DIM(p->pktq_out)); | |
1230 | uint32_t j; | |
1231 | ||
1232 | for (j = 0; j < n_pktq_out; j++) { | |
1233 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1234 | ||
1235 | if ((pktq->type == APP_PKTQ_OUT_KNI) && | |
1236 | (pktq->id == pos)) { | |
1237 | n_writers++; | |
1238 | writer = p; | |
1239 | id = j; | |
1240 | } | |
1241 | } | |
1242 | } | |
1243 | ||
1244 | if (n_writers != 1) | |
1245 | return NULL; | |
1246 | ||
1247 | *pktq_out_id = id; | |
1248 | return writer; | |
1249 | } | |
1250 | ||
1251 | static inline uint32_t | |
1252 | app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink) | |
1253 | { | |
1254 | uint32_t pos = sink - app->sink_params; | |
1255 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1256 | RTE_DIM(app->pipeline_params)); | |
1257 | uint32_t n_writers = 0, i; | |
1258 | ||
1259 | for (i = 0; i < n_pipelines; i++) { | |
1260 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1261 | uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out, | |
1262 | RTE_DIM(p->pktq_out)); | |
1263 | uint32_t j; | |
1264 | ||
1265 | for (j = 0; j < n_pktq_out; j++) { | |
1266 | struct app_pktq_out_params *pktq = &p->pktq_out[j]; | |
1267 | ||
1268 | if ((pktq->type == APP_PKTQ_OUT_SINK) && | |
1269 | (pktq->id == pos)) | |
1270 | n_writers++; | |
1271 | } | |
1272 | } | |
1273 | ||
1274 | return n_writers; | |
1275 | } | |
1276 | ||
1277 | static inline uint32_t | |
1278 | app_msgq_get_writers(struct app_params *app, struct app_msgq_params *msgq) | |
1279 | { | |
1280 | uint32_t pos = msgq - app->msgq_params; | |
1281 | uint32_t n_pipelines = RTE_MIN(app->n_pipelines, | |
1282 | RTE_DIM(app->pipeline_params)); | |
1283 | uint32_t n_writers = 0, i; | |
1284 | ||
1285 | for (i = 0; i < n_pipelines; i++) { | |
1286 | struct app_pipeline_params *p = &app->pipeline_params[i]; | |
1287 | uint32_t n_msgq_out = RTE_MIN(p->n_msgq_out, | |
1288 | RTE_DIM(p->msgq_out)); | |
1289 | uint32_t j; | |
1290 | ||
1291 | for (j = 0; j < n_msgq_out; j++) | |
1292 | if (p->msgq_out[j] == pos) | |
1293 | n_writers++; | |
1294 | } | |
1295 | ||
1296 | return n_writers; | |
1297 | } | |
1298 | ||
1299 | static inline struct app_link_params * | |
1300 | app_get_link_for_rxq(struct app_params *app, struct app_pktq_hwq_in_params *p) | |
1301 | { | |
1302 | char link_name[APP_PARAM_NAME_SIZE]; | |
1303 | ssize_t link_param_idx; | |
1304 | uint32_t rxq_link_id, rxq_queue_id; | |
1305 | ||
1306 | sscanf(p->name, "RXQ%" SCNu32 ".%" SCNu32, | |
1307 | &rxq_link_id, &rxq_queue_id); | |
1308 | sprintf(link_name, "LINK%" PRIu32, rxq_link_id); | |
1309 | link_param_idx = APP_PARAM_FIND(app->link_params, link_name); | |
1310 | APP_CHECK((link_param_idx >= 0), | |
1311 | "Cannot find %s for %s", link_name, p->name); | |
1312 | ||
1313 | return &app->link_params[link_param_idx]; | |
1314 | } | |
1315 | ||
1316 | static inline struct app_link_params * | |
1317 | app_get_link_for_txq(struct app_params *app, struct app_pktq_hwq_out_params *p) | |
1318 | { | |
1319 | char link_name[APP_PARAM_NAME_SIZE]; | |
1320 | ssize_t link_param_idx; | |
1321 | uint32_t txq_link_id, txq_queue_id; | |
1322 | ||
1323 | sscanf(p->name, "TXQ%" SCNu32 ".%" SCNu32, | |
1324 | &txq_link_id, &txq_queue_id); | |
1325 | sprintf(link_name, "LINK%" PRIu32, txq_link_id); | |
1326 | link_param_idx = APP_PARAM_FIND(app->link_params, link_name); | |
1327 | APP_CHECK((link_param_idx >= 0), | |
1328 | "Cannot find %s for %s", link_name, p->name); | |
1329 | ||
1330 | return &app->link_params[link_param_idx]; | |
1331 | } | |
1332 | ||
1333 | static inline struct app_link_params * | |
1334 | app_get_link_for_tm(struct app_params *app, struct app_pktq_tm_params *p_tm) | |
1335 | { | |
1336 | char link_name[APP_PARAM_NAME_SIZE]; | |
1337 | uint32_t link_id; | |
1338 | ssize_t link_param_idx; | |
1339 | ||
1340 | sscanf(p_tm->name, "TM%" PRIu32, &link_id); | |
1341 | sprintf(link_name, "LINK%" PRIu32, link_id); | |
1342 | link_param_idx = APP_PARAM_FIND(app->link_params, link_name); | |
1343 | APP_CHECK((link_param_idx >= 0), | |
1344 | "Cannot find %s for %s", link_name, p_tm->name); | |
1345 | ||
1346 | return &app->link_params[link_param_idx]; | |
1347 | } | |
1348 | ||
1349 | static inline struct app_link_params * | |
1350 | app_get_link_for_kni(struct app_params *app, struct app_pktq_kni_params *p_kni) | |
1351 | { | |
1352 | char link_name[APP_PARAM_NAME_SIZE]; | |
1353 | uint32_t link_id; | |
1354 | ssize_t link_param_idx; | |
1355 | ||
1356 | sscanf(p_kni->name, "KNI%" PRIu32, &link_id); | |
1357 | sprintf(link_name, "LINK%" PRIu32, link_id); | |
1358 | link_param_idx = APP_PARAM_FIND(app->link_params, link_name); | |
1359 | APP_CHECK((link_param_idx >= 0), | |
1360 | "Cannot find %s for %s", link_name, p_kni->name); | |
1361 | ||
1362 | return &app->link_params[link_param_idx]; | |
1363 | } | |
1364 | ||
11fdf7f2 TL |
1365 | static inline uint32_t |
1366 | app_core_is_enabled(struct app_params *app, uint32_t lcore_id) | |
1367 | { | |
1368 | return(app->core_mask[lcore_id / 64] & | |
1369 | (1LLU << (lcore_id % 64))); | |
1370 | } | |
1371 | ||
1372 | static inline void | |
1373 | app_core_enable_in_core_mask(struct app_params *app, int lcore_id) | |
1374 | { | |
1375 | app->core_mask[lcore_id / 64] |= 1LLU << (lcore_id % 64); | |
1376 | ||
1377 | } | |
1378 | ||
1379 | static inline void | |
1380 | app_core_build_core_mask_string(struct app_params *app, char *mask_buffer) | |
1381 | { | |
1382 | int i; | |
1383 | ||
1384 | mask_buffer[0] = '\0'; | |
1385 | for (i = (int)RTE_DIM(app->core_mask); i > 0; i--) { | |
1386 | /* For Hex representation of bits in uint64_t */ | |
1387 | char buffer[(64 / 8) * 2 + 1]; | |
1388 | memset(buffer, 0, sizeof(buffer)); | |
1389 | snprintf(buffer, sizeof(buffer), "%016" PRIx64, | |
1390 | app->core_mask[i-1]); | |
1391 | strcat(mask_buffer, buffer); | |
1392 | } | |
1393 | } | |
1394 | ||
7c673cae FG |
1395 | void app_pipeline_params_get(struct app_params *app, |
1396 | struct app_pipeline_params *p_in, | |
1397 | struct pipeline_params *p_out); | |
1398 | ||
1399 | int app_config_init(struct app_params *app); | |
1400 | ||
1401 | int app_config_args(struct app_params *app, | |
1402 | int argc, char **argv); | |
1403 | ||
1404 | int app_config_preproc(struct app_params *app); | |
1405 | ||
1406 | int app_config_parse(struct app_params *app, | |
1407 | const char *file_name); | |
1408 | ||
1409 | int app_config_parse_tm(struct app_params *app); | |
1410 | ||
1411 | void app_config_save(struct app_params *app, | |
1412 | const char *file_name); | |
1413 | ||
1414 | int app_config_check(struct app_params *app); | |
1415 | ||
1416 | int app_init(struct app_params *app); | |
1417 | ||
1418 | int app_post_init(struct app_params *app); | |
1419 | ||
1420 | int app_thread(void *arg); | |
1421 | ||
1422 | int app_pipeline_type_register(struct app_params *app, | |
1423 | struct pipeline_type *ptype); | |
1424 | ||
1425 | struct pipeline_type *app_pipeline_type_find(struct app_params *app, | |
1426 | char *name); | |
1427 | ||
1428 | void app_link_up_internal(struct app_params *app, | |
1429 | struct app_link_params *cp); | |
1430 | ||
1431 | void app_link_down_internal(struct app_params *app, | |
1432 | struct app_link_params *cp); | |
1433 | ||
1434 | #endif |