API Reference Manual 1.51.0
Loading...
Searching...
No Matches
odp_bench_pktio_sp.c
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2023-2025 Nokia
3 */
4
13#ifndef _GNU_SOURCE
14#define _GNU_SOURCE /* Needed for sigaction */
15#endif
16
17#include <odp_api.h>
18#include <odp/helper/odph_api.h>
19
20#include <bench_common.h>
21#include <export_results.h>
22
23#include <getopt.h>
24#include <inttypes.h>
25#include <signal.h>
26#include <stdlib.h>
27#include <unistd.h>
28
29/* Default number of rounds per test case */
30#define ROUNDS 100u
31
32/* Maximum interface name length */
33#define MAX_NAME_LEN 128
34
35/* Number of functions originally in test_suite */
36#define TEST_MAX_BENCH_NUM 10
37
38#define BENCH_INFO(run_fn, init_fn, term_fn, cond_fn, rounds) \
39 {.name = #run_fn, .run = run_fn, .init = init_fn, .term = term_fn, .cond = cond_fn,\
40 .max_rounds = rounds}
41
42typedef struct {
43 /* Command line options */
44 struct {
45 /* Rounds per test case */
46 uint32_t rounds;
47
48 /* Test case index to run */
49 uint32_t case_idx;
50
51 /* Interface name */
52 char name[MAX_NAME_LEN];
53
54 /* Packet input mode */
55 odp_pktin_mode_t in_mode;
56
57 /* Packet output mode */
58 odp_pktout_mode_t out_mode;
59
60 /* Number of packet input queues */
61 uint32_t num_input_queues;
62
63 /* Number of packet output queues */
64 uint32_t num_output_queues;
65
66 /* Number of PMRs */
67 uint32_t num_pmr;
68
69 /* Measure time vs. CPU cycles */
70 int time;
71 } opt;
72
73 /* Packet IO device */
74 odp_pktio_t pktio;
75
76 /* Packet IO capability*/
78
79 /* Packet pool */
80 odp_pool_t pool;
81
82 /* Packet IO statistics */
84
85 /* Input queue statistics */
86 odp_pktin_queue_stats_t pktin_queue_stats;
87
88 /* Output queue statistics */
89 odp_pktout_queue_stats_t pktout_queue_stats;
90
91 /* Data for cls_pmr_create() test */
92 struct {
93 /* Term used to create PMRs */
95
96 /* Is test enabled */
97 odp_bool_t enabled;
98
99 } cls_pmr_create;
100
101 /* Common benchmark suite data */
102 bench_tm_suite_t suite;
103
104 /* CPU mask as string */
105 char cpumask_str[ODP_CPUMASK_STR_SIZE];
106
107 /* Array for storing results */
108 bench_tm_result_t result[TEST_MAX_BENCH_NUM];
109
110} appl_args_t;
111
112static appl_args_t *gbl_args;
113
114static void sig_handler(int signo ODP_UNUSED)
115{
116 if (gbl_args == NULL)
117 return;
118 odp_atomic_store_u32(&gbl_args->suite.exit_worker, 1);
119}
120
121static int setup_sig_handler(void)
122{
123 struct sigaction action;
124
125 memset(&action, 0, sizeof(action));
126 action.sa_handler = sig_handler;
127
128 /* No additional signals blocked. By default, the signal which triggered
129 * the handler is blocked. */
130 if (sigemptyset(&action.sa_mask))
131 return -1;
132
133 if (sigaction(SIGINT, &action, NULL))
134 return -1;
135
136 return 0;
137}
138
139static void clean_pending_events(void)
140{
141 while (1) {
143
144 if (event != ODP_EVENT_INVALID) {
145 odp_event_free(event);
146 continue;
147 }
148 break;
149 };
150}
151
152static odp_pool_t create_packet_pool(void)
153{
155 odp_pool_param_t param;
156 odp_pool_t pool;
157
158 if (odp_pool_capability(&capa))
159 ODPH_ABORT("Reading pool capabilities failed\n");
160
161 odp_pool_param_init(&param);
162 param.type = ODP_POOL_PACKET;
163 param.pkt.num = 512;
164 param.pkt.len = 2048;
165
166 if (capa.pkt.max_num && capa.pkt.max_num < param.pkt.num)
167 param.pkt.num = capa.pkt.max_num;
168
169 if (capa.pkt.max_len && capa.pkt.max_len < param.pkt.len)
170 param.pkt.len = capa.pkt.max_len;
171
172 pool = odp_pool_create("pktio_pool", &param);
173 if (pool == ODP_POOL_INVALID)
174 ODPH_ABORT("Creating packet pool failed\n");
175
176 return pool;
177}
178
179static void pktio_setup_param(odp_pktin_mode_t in_mode, odp_pktout_mode_t out_mode, odp_bool_t cls)
180{
181 appl_args_t *appl_args = gbl_args;
182 odp_pktio_param_t param;
183 odp_pktin_queue_param_t pktin_param;
184 odp_pktout_queue_param_t pktout_param;
185 odp_pktio_t pktio;
186 odp_pool_t pool;
187 int ret;
188
189 pool = create_packet_pool();
190
191 odp_pktio_param_init(&param);
192 param.in_mode = in_mode;
193 param.out_mode = out_mode;
194
195 pktio = odp_pktio_open(appl_args->opt.name, pool, &param);
196 if (pktio == ODP_PKTIO_INVALID)
197 ODPH_ABORT("Opening pktio failed\n");
198
199 odp_pktin_queue_param_init(&pktin_param);
200 pktin_param.num_queues = appl_args->opt.num_input_queues;
201
202 if (cls) {
203 pktin_param.classifier_enable = true;
204 } else {
205 if (pktin_param.num_queues > 1) {
206 pktin_param.hash_enable = true;
207 pktin_param.hash_proto.proto.ipv4_udp = 1;
208 }
209 }
210
211 odp_pktout_queue_param_init(&pktout_param);
212 pktout_param.num_queues = appl_args->opt.num_output_queues;
213
214 ret = odp_pktin_queue_config(pktio, &pktin_param);
215 if (ret)
216 ODPH_ABORT("Configuring packet input queues failed: %d\n", ret);
217
218 ret = odp_pktout_queue_config(pktio, &pktout_param);
219 if (ret)
220 ODPH_ABORT("Configuring packet output queues failed: %d\n", ret);
221
222 ret = odp_pktio_start(pktio);
223 if (ret)
224 ODPH_ABORT("Starting pktio failed: %d\n", ret);
225
226 appl_args->pool = pool;
227 appl_args->pktio = pktio;
228}
229
230static void pktio_setup(void)
231{
232 pktio_setup_param(gbl_args->opt.in_mode, gbl_args->opt.out_mode, false);
233}
234
235static void pktio_setup_direct_rx(void)
236{
237 pktio_setup_param(ODP_PKTIN_MODE_DIRECT, gbl_args->opt.out_mode, false);
238}
239
240static void pktio_setup_sched_rx(void)
241{
242 pktio_setup_param(ODP_PKTIN_MODE_SCHED, gbl_args->opt.out_mode, false);
243}
244
245static void pktio_setup_cls(void)
246{
247 pktio_setup_param(ODP_PKTIN_MODE_SCHED, gbl_args->opt.out_mode, true);
248}
249
250static void pktio_setup_direct_tx(void)
251{
252 pktio_setup_param(gbl_args->opt.in_mode, ODP_PKTOUT_MODE_DIRECT, false);
253}
254
255static void pktio_setup_queue_tx(void)
256{
257 pktio_setup_param(gbl_args->opt.in_mode, ODP_PKTOUT_MODE_QUEUE, false);
258}
259
260static void pktio_clean_param(odp_pktin_mode_t in_mode)
261{
262 appl_args_t *appl_args = gbl_args;
263 int ret;
264
265 ret = odp_pktio_stop(appl_args->pktio);
266 if (ret)
267 ODPH_ABORT("Stopping pktio failed: %d\n", ret);
268
269 /* Clean possible pre-scheduled packets */
270 if (in_mode == ODP_PKTIN_MODE_SCHED)
271 clean_pending_events();
272
273 ret = odp_pktio_close(appl_args->pktio);
274 if (ret)
275 ODPH_ABORT("Closing pktio failed: %d\n", ret);
276
277 ret = odp_pool_destroy(appl_args->pool);
278 if (ret)
279 ODPH_ABORT("Destroying pktio pool failed: %d\n", ret);
280}
281
282static void pktio_clean(void)
283{
284 pktio_clean_param(gbl_args->opt.in_mode);
285}
286
287static void pktio_clean_direct_rx(void)
288{
289 pktio_clean_param(ODP_PKTIN_MODE_DIRECT);
290}
291
292static void pktio_clean_sched_rx(void)
293{
294 pktio_clean_param(ODP_PKTIN_MODE_SCHED);
295}
296
297static int pktio_capability(bench_tm_result_t *res, int repeat_count)
298{
299 appl_args_t *appl_args = gbl_args;
300 odp_pktio_capability_t *capa = &appl_args->capa;
301 odp_pktio_t pktio = appl_args->pktio;
302 bench_tm_stamp_t s1, s2;
303 int ret;
304 uint8_t id1 = bench_tm_func_register(res, "odp_pktio_capability()");
305
306 for (int i = 0; i < repeat_count; i++) {
307 bench_tm_now(res, &s1);
308 ret = odp_pktio_capability(pktio, capa);
309 bench_tm_now(res, &s2);
310
311 if (ret) {
312 ODPH_ERR("Reading pktio capa failed: %d\n", ret);
313 return 0;
314 }
315
316 bench_tm_func_record(&s2, &s1, res, id1);
317 }
318 return 1;
319}
320
321static int pktio_lookup(bench_tm_result_t *res, int repeat_count)
322{
323 appl_args_t *appl_args = gbl_args;
324 const char *name = appl_args->opt.name;
325 odp_pktio_t pktio;
326 bench_tm_stamp_t s1, s2;
327 uint8_t id1 = bench_tm_func_register(res, "odp_pktio_lookup()");
328
329 for (int i = 0; i < repeat_count; i++) {
330 bench_tm_now(res, &s1);
331 pktio = odp_pktio_lookup(name);
332 bench_tm_now(res, &s2);
333
334 if (pktio == ODP_PKTIO_INVALID) {
335 ODPH_ERR("Pktio lookup failed\n");
336 return 0;
337 }
338
339 bench_tm_func_record(&s2, &s1, res, id1);
340 }
341 return 1;
342}
343
344static int pktio_open_start_stop_close(bench_tm_result_t *res, int repeat_count)
345{
346 appl_args_t *appl_args = gbl_args;
347 odp_pktio_param_t param;
348 odp_pktin_queue_param_t pktin_param;
349 odp_pktout_queue_param_t pktout_param;
350 odp_pktio_t pktio;
351 odp_pool_t pool;
352 bench_tm_stamp_t s1, s2, s3, s4, s5, s6, s7, s8;
353 int ret;
354 uint8_t id1 = bench_tm_func_register(res, "odp_pktio_open()");
355 uint8_t id2 = bench_tm_func_register(res, "odp_pktin_queue_config()");
356 uint8_t id3 = bench_tm_func_register(res, "odp_pktout_queue_config()");
357 uint8_t id4 = bench_tm_func_register(res, "odp_pktio_start()");
358 uint8_t id5 = bench_tm_func_register(res, "odp_pktio_stop()");
359 uint8_t id6 = bench_tm_func_register(res, "odp_pktio_close()");
360
361 pool = create_packet_pool();
362
363 odp_pktio_param_init(&param);
364 param.in_mode = appl_args->opt.in_mode;
365 param.out_mode = appl_args->opt.out_mode;
366
367 odp_pktin_queue_param_init(&pktin_param);
368 pktin_param.num_queues = appl_args->opt.num_input_queues;
369 if (pktin_param.num_queues > 1) {
370 pktin_param.hash_enable = true;
371 pktin_param.hash_proto.proto.ipv4_udp = 1;
372 }
373
374 odp_pktout_queue_param_init(&pktout_param);
375 pktout_param.num_queues = appl_args->opt.num_output_queues;
376
377 for (int i = 0; i < repeat_count; i++) {
378 bench_tm_now(res, &s1);
379 pktio = odp_pktio_open(appl_args->opt.name, pool, &param);
380 bench_tm_now(res, &s2);
381
382 if (pktio == ODP_PKTIO_INVALID) {
383 ODPH_ERR("Opening pktio failed\n");
384 return 0;
385 }
386
387 ret = odp_pktin_queue_config(pktio, &pktin_param);
388 bench_tm_now(res, &s3);
389
390 if (ret) {
391 ODPH_ERR("Configuring packet input queues failed: %d\n", ret);
392 return 0;
393 }
394
395 ret = odp_pktout_queue_config(pktio, &pktout_param);
396 bench_tm_now(res, &s4);
397
398 if (ret) {
399 ODPH_ERR("Configuring packet output queues failed: %d\n", ret);
400 return 0;
401 }
402
403 ret = odp_pktio_start(pktio);
404 bench_tm_now(res, &s5);
405
406 if (ret) {
407 ODPH_ERR("Starting pktio failed: %d\n", ret);
408 return 0;
409 }
410
411 ret = odp_pktio_stop(pktio);
412 bench_tm_now(res, &s6);
413
414 if (ret) {
415 ODPH_ERR("Stopping pktio failed: %d\n", ret);
416 return 0;
417 }
418
419 /* Clean possible pre-scheduled packets */
420 if (appl_args->opt.in_mode == ODP_PKTIN_MODE_SCHED)
421 clean_pending_events();
422
423 bench_tm_now(res, &s7);
424 ret = odp_pktio_close(pktio);
425 bench_tm_now(res, &s8);
426 if (ret) {
427 ODPH_ERR("Closing pktio failed: %d\n", ret);
428 return 0;
429 }
430
431 bench_tm_func_record(&s2, &s1, res, id1);
432 bench_tm_func_record(&s3, &s2, res, id2);
433 bench_tm_func_record(&s4, &s3, res, id3);
434 bench_tm_func_record(&s5, &s4, res, id4);
435 bench_tm_func_record(&s6, &s5, res, id5);
436 bench_tm_func_record(&s8, &s7, res, id6);
437 }
438
439 ret = odp_pool_destroy(pool);
440 if (ret) {
441 ODPH_ERR("Destroying pktio pool failed: %d\n", ret);
442 return 0;
443 }
444 return 1;
445}
446
447static int pktio_stats(bench_tm_result_t *res, int repeat_count)
448{
449 appl_args_t *appl_args = gbl_args;
450 odp_pktio_stats_t *stats = &appl_args->stats;
451 odp_pktio_t pktio = appl_args->pktio;
452 bench_tm_stamp_t s1, s2;
453 int ret;
454 uint8_t id1 = bench_tm_func_register(res, "odp_pktio_stats()");
455
456 for (int i = 0; i < repeat_count; i++) {
457 bench_tm_now(res, &s1);
458 ret = odp_pktio_stats(pktio, stats);
459 bench_tm_now(res, &s2);
460
461 if (ret) {
462 ODPH_ERR("Reading pktio stats failed\n");
463 return 0;
464 }
465
466 bench_tm_func_record(&s2, &s1, res, id1);
467 }
468 return 1;
469}
470
471static int pktio_stats_reset(bench_tm_result_t *res, int repeat_count)
472{
473 appl_args_t *appl_args = gbl_args;
474 odp_pktio_t pktio = appl_args->pktio;
475 bench_tm_stamp_t s1, s2;
476 int ret;
477 int id1 = bench_tm_func_register(res, "odp_pktio_stats_reset()");
478
479 for (int i = 0; i < repeat_count; i++) {
480 bench_tm_now(res, &s1);
481 ret = odp_pktio_stats_reset(pktio);
482 bench_tm_now(res, &s2);
483
484 if (ret) {
485 ODPH_ERR("Resetting pktio stats failed\n");
486 return 0;
487 }
488
489 bench_tm_func_record(&s2, &s1, res, id1);
490 }
491 return 1;
492}
493
494static int pktin_queue_stats(bench_tm_result_t *res, int repeat_count)
495{
496 appl_args_t *appl_args = gbl_args;
497 odp_pktin_queue_stats_t *stats = &appl_args->pktin_queue_stats;
498 odp_pktio_t pktio = appl_args->pktio;
499 odp_pktin_queue_t queue;
500 bench_tm_stamp_t s1, s2;
501 int ret;
502 uint8_t id1 = bench_tm_func_register(res, "odp_pktin_queue_stats()");
503
504 ret = odp_pktin_queue(pktio, &queue, 1);
505 if (ret < 1) {
506 ODPH_ERR("Reading pktio input queue failed\n");
507 return 0;
508 }
509
510 for (int i = 0; i < repeat_count; i++) {
511 bench_tm_now(res, &s1);
512 ret = odp_pktin_queue_stats(queue, stats);
513 bench_tm_now(res, &s2);
514
515 if (ret) {
516 ODPH_ERR("Reading pktio stats failed\n");
517 return 0;
518 }
519
520 bench_tm_func_record(&s2, &s1, res, id1);
521 }
522 return 1;
523}
524
525static int pktin_event_queue_stats(bench_tm_result_t *res, int repeat_count)
526{
527 appl_args_t *appl_args = gbl_args;
528 odp_pktin_queue_stats_t *stats = &appl_args->pktin_queue_stats;
529 odp_pktio_t pktio = appl_args->pktio;
530 odp_queue_t queue;
531 bench_tm_stamp_t s1, s2;
532 int ret;
533 uint8_t id1 = bench_tm_func_register(res, "odp_pktin_event_queue_stats()");
534
535 ret = odp_pktin_event_queue(pktio, &queue, 1);
536 if (ret < 1) {
537 ODPH_ERR("Reading pktio input queue failed\n");
538 return 0;
539 }
540
541 for (int i = 0; i < repeat_count; i++) {
542 bench_tm_now(res, &s1);
543 ret = odp_pktin_event_queue_stats(pktio, queue, stats);
544 bench_tm_now(res, &s2);
545
546 if (ret) {
547 ODPH_ERR("Reading pktio stats failed\n");
548 return 0;
549 }
550
551 bench_tm_func_record(&s2, &s1, res, id1);
552 }
553 return 1;
554}
555
556static int pktout_queue_stats(bench_tm_result_t *res, int repeat_count)
557{
558 appl_args_t *appl_args = gbl_args;
559 odp_pktout_queue_stats_t *stats = &appl_args->pktout_queue_stats;
560 odp_pktio_t pktio = appl_args->pktio;
561 odp_pktout_queue_t queue;
562 bench_tm_stamp_t s1, s2;
563 int ret;
564 uint8_t id1 = bench_tm_func_register(res, "odp_pktout_queue_stats()");
565
566 ret = odp_pktout_queue(pktio, &queue, 1);
567 if (ret < 1) {
568 ODPH_ERR("Reading pktio input queue failed\n");
569 return 0;
570 }
571
572 for (int i = 0; i < repeat_count; i++) {
573 bench_tm_now(res, &s1);
574 ret = odp_pktout_queue_stats(queue, stats);
575 bench_tm_now(res, &s2);
576
577 if (ret) {
578 ODPH_ERR("Reading pktio stats failed\n");
579 return 0;
580 }
581
582 bench_tm_func_record(&s2, &s1, res, id1);
583 }
584 return 1;
585}
586
587static int pktout_event_queue_stats(bench_tm_result_t *res, int repeat_count)
588{
589 appl_args_t *appl_args = gbl_args;
590 odp_pktout_queue_stats_t *stats = &appl_args->pktout_queue_stats;
591 odp_pktio_t pktio = appl_args->pktio;
592 odp_queue_t queue;
593 bench_tm_stamp_t s1, s2;
594 int ret;
595 uint8_t id1 = bench_tm_func_register(res, "odp_pktout_event_queue_stats()");
596
597 ret = odp_pktout_event_queue(pktio, &queue, 1);
598 if (ret < 1) {
599 ODPH_ERR("Reading pktio input queue failed\n");
600 return 0;
601 }
602
603 for (int i = 0; i < repeat_count; i++) {
604 bench_tm_now(res, &s1);
605 ret = odp_pktout_event_queue_stats(pktio, queue, stats);
606 bench_tm_now(res, &s2);
607
608 if (ret) {
609 ODPH_ERR("Reading pktio stats failed\n");
610 return 0;
611 }
612
613 bench_tm_func_record(&s2, &s1, res, id1);
614 }
615 return 1;
616}
617
618static int find_first_supported_l3_pmr(const odp_cls_capability_t *capa, odp_cls_pmr_term_t *term)
619{
620 *term = ODP_PMR_TCP_DPORT;
621
622 if (capa->supported_terms.bit.udp_sport)
623 *term = ODP_PMR_UDP_SPORT;
624 else if (capa->supported_terms.bit.udp_dport)
625 *term = ODP_PMR_UDP_DPORT;
626 else if (capa->supported_terms.bit.tcp_sport)
627 *term = ODP_PMR_TCP_SPORT;
628 else if (capa->supported_terms.bit.tcp_dport)
629 *term = ODP_PMR_TCP_DPORT;
630 else
631 return 0;
632
633 return 1;
634}
635
636/* Capabilities required for cls_pmr_create() test */
637static int check_cls_capa(void)
638{
639 appl_args_t *appl_args = gbl_args;
640 odp_cls_capability_t cls_capa;
641 odp_schedule_capability_t sched_capa;
642 int ret;
643
644 ret = odp_cls_capability(&cls_capa);
645 if (ret) {
646 ODPH_ERR("Reading classifier capa failed: %d\n", ret);
647 return -1;
648 }
649
650 ret = odp_schedule_capability(&sched_capa);
651 if (ret) {
652 ODPH_ERR("Reading scheduler capa failed: %d\n", ret);
653 return -1;
654 }
655
656 if (!find_first_supported_l3_pmr(&cls_capa, &appl_args->cls_pmr_create.term)) {
657 ODPH_ERR("Implementations doesn't support any TCP/UDP PMRs\n");
658 return 0;
659 }
660
661 /* One extra CoS and queue required for the default CoS */
662 if (appl_args->opt.num_pmr + 1 > cls_capa.max_cos) {
663 ODPH_ERR("Not enough CoSes supported for PMR test: %u/%u\n",
664 appl_args->opt.num_pmr + 1, cls_capa.max_cos);
665 return 0;
666 }
667
668 if (appl_args->opt.num_pmr + 1 > sched_capa.max_queues) {
669 ODPH_ERR("Not enough queues supported for PMR test: %u/%u\n",
670 appl_args->opt.num_pmr + 1, sched_capa.max_queues);
671 return 0;
672 }
673
674 appl_args->cls_pmr_create.enabled = true;
675
676 return 1;
677}
678
679static int check_cls_cond(void)
680{
681 return gbl_args->cls_pmr_create.enabled;
682}
683
684static int cls_pmr_create(bench_tm_result_t *res, int repeat_count)
685{
686 appl_args_t *appl_args = gbl_args;
687 odp_pktio_t pktio = appl_args->pktio;
688 odp_cls_cos_param_t cos_param;
689 odp_queue_param_t queue_param;
690 odp_pmr_param_t pmr_param;
691 odp_cos_t default_cos;
692 uint32_t num_cos = appl_args->opt.num_pmr + 1;
693 uint32_t num_pmr = num_cos - 1;
694 uint32_t cos_created = 0;
695 uint32_t queue_created = 0;
696 uint16_t val = 1024;
697 uint16_t mask = 0xffff;
698 int ret = 0;
699 bench_tm_stamp_t s1, s2;
700 odp_cos_t cos[num_cos];
701 odp_queue_t queue[num_cos];
702 odp_pmr_t pmr[num_pmr];
703 uint8_t id1 = bench_tm_func_register(res, "odp_cls_pmr_create()");
704 uint8_t id2 = bench_tm_func_register(res, "odp_cls_pmr_destroy()");
705
706 odp_queue_param_init(&queue_param);
707 queue_param.type = ODP_QUEUE_TYPE_SCHED;
708
709 odp_cls_cos_param_init(&cos_param);
710
711 for (uint32_t i = 0; i < num_cos; i++) {
712 queue[i] = odp_queue_create(NULL, &queue_param);
713 if (queue[i] == ODP_QUEUE_INVALID) {
714 ODPH_ERR("odp_queue_create() failed %u / %u\n", i + 1, num_cos);
715 break;
716 }
717
718 cos_param.queue = queue[i];
719 queue_created++;
720
721 cos[i] = odp_cls_cos_create(NULL, &cos_param);
722 if (cos[i] == ODP_COS_INVALID) {
723 ODPH_ERR("odp_cls_cos_create() failed %u / %u\n", i + 1, num_cos);
724 break;
725 }
726 cos_created++;
727 }
728
729 if (queue_created != num_cos)
730 ODPH_ERR("Unable to create all queues: %u/%u\n", queue_created, num_cos);
731
732 if (cos_created != num_cos) {
733 ODPH_ERR("Unable to create all CoSes: %u/%u\n", cos_created, num_cos);
734 goto destroy_cos;
735 }
736
737 default_cos = cos[0];
738
739 ret = odp_pktio_default_cos_set(pktio, default_cos);
740 if (ret) {
741 ODPH_ERR("Setting default CoS failed: %d\n", ret);
742 goto destroy_cos;
743 }
744
745 odp_cls_pmr_param_init(&pmr_param);
746 pmr_param.term = appl_args->cls_pmr_create.term;
747 pmr_param.match.value = &val;
748 pmr_param.match.mask = &mask;
749 pmr_param.val_sz = sizeof(val);
750
751 for (uint32_t i = 0; i < (uint32_t)repeat_count; i++) {
752 uint32_t pmr_created = 0;
753
754 for (uint32_t j = 0; j < num_pmr; j++) {
755 bench_tm_now(res, &s1);
756 pmr[j] = odp_cls_pmr_create(&pmr_param, 1, default_cos, cos[j + 1]);
757 bench_tm_now(res, &s2);
758
759 if (pmr[j] == ODP_PMR_INVALID)
760 break;
761 bench_tm_func_record(&s2, &s1, res, id1);
762
763 val++;
764 pmr_created++;
765 }
766
767 for (uint32_t j = 0; j < pmr_created; j++) {
768 bench_tm_now(res, &s1);
769 ret = odp_cls_pmr_destroy(pmr[j]);
770 bench_tm_now(res, &s2);
771
772 if (ret)
773 ODPH_ABORT("Destroying PMR failed: %d\n", ret);
774
775 bench_tm_func_record(&s2, &s1, res, id2);
776 }
777
778 if (i == 0)
779 ODPH_DBG("Created %u PMRs\n", pmr_created);
780 }
781
783
784 if (ret < 0) {
785 ODPH_ERR("Setting default CoS failed: %d\n", ret);
786 return 0;
787 }
788
789destroy_cos:
790 for (uint32_t i = 0; i < cos_created; i++) {
791 ret = odp_cos_destroy(cos[i]);
792
793 if (ret < 0) {
794 ODPH_ERR("Destroying CoS failed: %d\n", ret);
795 return 0;
796 }
797 }
798
799 for (uint32_t i = 0; i < queue_created; i++) {
800 ret = odp_queue_destroy(queue[i]);
801
802 if (ret < 0) {
803 ODPH_ERR("Destroying queue failed: %d\n", ret);
804 return 0;
805 }
806 }
807
808 return 1;
809}
810
811static int bench_pktio_sp_export(void *data)
812{
813 appl_args_t *gbl_args = data;
814 bench_tm_result_t *res;
815 uint64_t num;
816 int ret = 0;
817 const char *unit = gbl_args->opt.time ? "nsec" : "cycles";
818
819 if (test_common_write("function name,latency (%s) per function call (min),"
820 "latency (%s) per function call (avg),"
821 "latency (%s) per function call (max)\n", unit, unit, unit)) {
822 ret = -1;
823 goto exit;
824 }
825
826 for (uint32_t i = 0; i < gbl_args->suite.num_bench; i++) {
827 res = &gbl_args->result[i];
828
829 for (int j = 0; j < res->num; j++) {
830 num = res->func[j].num ? res->func[j].num : 1;
831 if (test_common_write("%s,%" PRIu64 ",%" PRIu64 ",%" PRIu64 "\n",
832 res->func[j].name,
833 bench_tm_to_u64(res, &res->func[j].min),
834 bench_tm_to_u64(res, &res->func[j].tot) / num,
835 bench_tm_to_u64(res, &res->func[j].max))) {
836 ret = -1;
837 goto exit;
838 }
839 }
840 }
841
842exit:
843 test_common_write_term();
844
845 return ret;
846}
847
848bench_tm_info_t test_suite[] = {
849 BENCH_INFO(pktio_capability, pktio_setup, pktio_clean, NULL, 0),
850 BENCH_INFO(pktio_lookup, pktio_setup, pktio_clean, NULL, 0),
851 BENCH_INFO(pktio_open_start_stop_close, NULL, NULL, NULL, 0),
852 BENCH_INFO(pktio_stats, pktio_setup, pktio_clean, NULL, 0),
853 BENCH_INFO(pktin_queue_stats, pktio_setup_direct_rx, pktio_clean_direct_rx, NULL, 0),
854 BENCH_INFO(pktin_event_queue_stats, pktio_setup_sched_rx, pktio_clean_sched_rx, NULL, 0),
855 BENCH_INFO(pktout_queue_stats, pktio_setup_direct_tx, pktio_clean, NULL, 0),
856 BENCH_INFO(pktout_event_queue_stats, pktio_setup_queue_tx, pktio_clean, NULL, 0),
857 BENCH_INFO(pktio_stats_reset, pktio_setup, pktio_clean, NULL, 0),
858 BENCH_INFO(cls_pmr_create, pktio_setup_cls, pktio_clean_sched_rx, check_cls_cond, 0)
859};
860
861ODP_STATIC_ASSERT(ODPH_ARRAY_SIZE(test_suite) <= TEST_MAX_BENCH_NUM,
862 "Result array is too small to hold all the results");
863
864/* Print usage information */
865static void usage(void)
866{
867 printf("\n"
868 "ODP pktio API slow path micro benchmarks\n"
869 "\n"
870 "Options:\n"
871 " -i, --interface <name> Ethernet interface name (default loop).\n"
872 " -m, --in_mode <arg> Packet input mode\n"
873 " 0: Direct mode: PKTIN_MODE_DIRECT (default)\n"
874 " 1: Scheduler mode with parallel queues:\n"
875 " PKTIN_MODE_SCHED + SCHED_SYNC_PARALLEL\n"
876 " -o, --out_mode <arg> Packet output mode\n"
877 " 0: Direct mode: PKTOUT_MODE_DIRECT (default)\n"
878 " 1: Queue mode: PKTOUT_MODE_QUEUE\n"
879 " -p, --pmr <num> Number of PMRs to create/destroy per round (default 1)\n"
880 " -q, --rx_queues <num> Number of packet input queues (default 1)\n"
881 " -t, --tx_queues <num> Number of packet output queues (default 1)\n"
882 " -r, --rounds <num> Run each test case 'num' times (default %u).\n"
883 " -s, --select <idx> Run only selected test case.\n"
884 " -T, --time <opt> Time measurement. 0: measure CPU cycles (default), 1: measure time\n"
885 " -h, --help Display help and exit.\n\n"
886 "\n", ROUNDS);
887}
888
889static int parse_interface(appl_args_t *appl_args, const char *optarg)
890{
891 if (strlen(optarg) + 1 > MAX_NAME_LEN) {
892 ODPH_ERR("Unable to store interface name (MAX_NAME_LEN=%d)\n", MAX_NAME_LEN);
893 return -1;
894 }
895 odph_strcpy(appl_args->opt.name, optarg, MAX_NAME_LEN);
896 return 0;
897}
898
899/* Parse command line arguments */
900static int parse_args(int argc, char *argv[])
901{
902 int i;
903 int opt;
904 static const struct option longopts[] = {
905 {"interface", required_argument, NULL, 'i'},
906 {"in_mode", required_argument, NULL, 'm'},
907 {"out_mode", required_argument, NULL, 'o'},
908 {"pmr", required_argument, NULL, 'p'},
909 {"rx_queues", required_argument, NULL, 'q'},
910 {"tx_queues", required_argument, NULL, 't'},
911 {"rounds", required_argument, NULL, 'r'},
912 {"select", required_argument, NULL, 's'},
913 {"time", required_argument, NULL, 'T'},
914 {"help", no_argument, NULL, 'h'},
915 {NULL, 0, NULL, 0}
916 };
917
918 static const char *shortopts = "i:m:o:p:q:r:s:t:T:h";
919
920 odph_strcpy(gbl_args->opt.name, "loop", MAX_NAME_LEN);
921 gbl_args->opt.rounds = ROUNDS;
922 gbl_args->opt.in_mode = ODP_PKTIN_MODE_DIRECT;
923 gbl_args->opt.out_mode = ODP_PKTOUT_MODE_DIRECT;
924 gbl_args->opt.num_input_queues = 1;
925 gbl_args->opt.num_output_queues = 1;
926 gbl_args->opt.num_pmr = 1;
927
928 while (1) {
929 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
930
931 if (opt == -1)
932 break; /* No more options */
933
934 switch (opt) {
935 case 'i':
936 if (parse_interface(gbl_args, optarg))
937 return -1;
938 break;
939 case 'm':
940 i = atoi(optarg);
941 if (i == 1)
942 gbl_args->opt.in_mode = ODP_PKTIN_MODE_SCHED;
943 else
944 gbl_args->opt.in_mode = ODP_PKTIN_MODE_DIRECT;
945 break;
946 case 'o':
947 i = atoi(optarg);
948 if (i == 1)
949 gbl_args->opt.out_mode = ODP_PKTOUT_MODE_QUEUE;
950 else
951 gbl_args->opt.out_mode = ODP_PKTOUT_MODE_DIRECT;
952 break;
953 case 'p':
954 gbl_args->opt.num_pmr = atoi(optarg);
955 break;
956 case 'q':
957 gbl_args->opt.num_input_queues = atoi(optarg);
958 break;
959 case 'r':
960 gbl_args->opt.rounds = atoi(optarg);
961 break;
962 case 's':
963 gbl_args->opt.case_idx = atoi(optarg);
964 break;
965 case 't':
966 gbl_args->opt.num_output_queues = atoi(optarg);
967 break;
968 case 'T':
969 gbl_args->opt.time = atoi(optarg);
970 break;
971 case 'h':
972 usage();
973 return 1;
974 default:
975 ODPH_ERR("Bad option. Use -h for help.\n");
976 return -1;
977 }
978 }
979
980 return 0;
981}
982
983static int check_args(appl_args_t *appl_args)
984{
985 odp_pktio_param_t param;
987 odp_pktio_t pktio;
988 odp_pool_t pool;
989 int ret;
990
991 if (gbl_args->opt.rounds < 1) {
992 ODPH_ERR("Invalid test repeat count: %u\n", gbl_args->opt.rounds);
993 return -1;
994 }
995
996 if (gbl_args->opt.case_idx > ODPH_ARRAY_SIZE(test_suite)) {
997 ODPH_ERR("Invalid test case index: %u\n", gbl_args->opt.case_idx);
998 return -1;
999 }
1000
1001 pool = create_packet_pool();
1002
1003 odp_pktio_param_init(&param);
1004 param.in_mode = appl_args->opt.in_mode;
1005 param.out_mode = appl_args->opt.out_mode;
1006
1007 pktio = odp_pktio_open(appl_args->opt.name, pool, &param);
1008 if (pktio == ODP_PKTIO_INVALID) {
1009 ODPH_ERR("Opening pktio failed\n");
1010 return -1;
1011 }
1012
1013 ret = odp_pktio_capability(pktio, &capa);
1014 if (ret) {
1015 ODPH_ERR("Reading pktio capa failed: %d\n", ret);
1016 return -1;
1017 }
1018
1019 if (appl_args->opt.num_input_queues > capa.max_input_queues) {
1020 ODPH_ERR("Too many input queues: %u/%u\n", appl_args->opt.num_input_queues,
1021 capa.max_input_queues);
1022 return -1;
1023 }
1024
1025 if (appl_args->opt.num_output_queues > capa.max_output_queues) {
1026 ODPH_ERR("Too many output queues: %u/%u\n", appl_args->opt.num_output_queues,
1027 capa.max_output_queues);
1028 return -1;
1029 }
1030
1031 ret = odp_pktio_close(pktio);
1032 if (ret) {
1033 ODPH_ERR("Closing pktio failed: %d\n", ret);
1034 return -1;
1035 }
1036
1037 ret = odp_pool_destroy(pool);
1038 if (ret) {
1039 ODPH_ERR("Destroying pktio pool failed: %d\n", ret);
1040 return -1;
1041 }
1042
1043 if (check_cls_capa() < 0)
1044 return -1;
1045
1046 return 0;
1047}
1048
1049/* Print application info */
1050static void print_info(appl_args_t *appl_args)
1051{
1053
1054 printf("\n"
1055 "odp_bench_pktio_sp options\n"
1056 "--------------------------\n");
1057
1058 printf("CPU mask: %s\n", gbl_args->cpumask_str);
1059 printf("Interface: %s\n", gbl_args->opt.name);
1060
1061 printf("Input mode: ");
1062 if (appl_args->opt.in_mode == ODP_PKTIN_MODE_SCHED)
1063 printf("sched\n");
1064 else
1065 printf("direct\n");
1066
1067 printf("Output mode: ");
1068 if (appl_args->opt.out_mode == ODP_PKTOUT_MODE_QUEUE)
1069 printf("plain\n");
1070 else
1071 printf("direct\n");
1072
1073 printf("Input queues: %u\n", gbl_args->opt.num_input_queues);
1074 printf("Output queues: %u\n", gbl_args->opt.num_output_queues);
1075 printf("PMRs: %u\n", gbl_args->opt.num_pmr);
1076 printf("Measurement unit: %s\n", gbl_args->opt.time ? "nsec" : "CPU cycles");
1077 printf("Test rounds: %d\n", gbl_args->opt.rounds);
1078 printf("\n");
1079}
1080
1081int main(int argc, char *argv[])
1082{
1083 odph_helper_options_t helper_options;
1084 test_common_options_t common_options;
1085 odph_thread_t worker_thread;
1086 odph_thread_common_param_t thr_common;
1087 odph_thread_param_t thr_param;
1088 odp_shm_t shm;
1089 odp_cpumask_t cpumask, default_mask;
1090 odp_instance_t instance;
1091 odp_init_t init_param;
1092 int cpu;
1093 int ret;
1094
1095 /* Let helper collect its own arguments (e.g. --odph_proc) */
1096 argc = odph_parse_options(argc, argv);
1097 if (odph_options(&helper_options)) {
1098 ODPH_ERR("Reading ODP helper options failed\n");
1099 exit(EXIT_FAILURE);
1100 }
1101
1102 argc = test_common_parse_options(argc, argv);
1103 if (test_common_options(&common_options)) {
1104 ODPH_ERR("Reading test options failed\n");
1105 exit(EXIT_FAILURE);
1106 }
1107
1108 odp_init_param_init(&init_param);
1109 init_param.mem_model = helper_options.mem_model;
1110
1111 /* Init ODP before calling anything else */
1112 if (odp_init_global(&instance, &init_param, NULL)) {
1113 ODPH_ERR("Global init failed\n");
1114 exit(EXIT_FAILURE);
1115 }
1116
1117 /* Init this thread */
1118 if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
1119 ODPH_ERR("Local init failed\n");
1120 exit(EXIT_FAILURE);
1121 }
1122
1123 ret = odp_schedule_config(NULL);
1124 if (ret) {
1125 ODPH_ERR("Schedule config failed: %d\n", ret);
1126 exit(EXIT_FAILURE);
1127 }
1128
1129 if (setup_sig_handler()) {
1130 ODPH_ERR("Signal handler setup failed\n");
1131 exit(EXIT_FAILURE);
1132 }
1133
1134 /* Reserve memory for args from shared mem */
1135 shm = odp_shm_reserve("shm_args", sizeof(appl_args_t), ODP_CACHE_LINE_SIZE, 0);
1136 if (shm == ODP_SHM_INVALID) {
1137 ODPH_ERR("Shared mem reserve failed\n");
1138 exit(EXIT_FAILURE);
1139 }
1140
1141 gbl_args = odp_shm_addr(shm);
1142 if (gbl_args == NULL) {
1143 ODPH_ERR("Shared mem alloc failed\n");
1144 exit(EXIT_FAILURE);
1145 }
1146
1147 memset(gbl_args, 0, sizeof(appl_args_t));
1148
1149 /* Parse and store the application arguments */
1150 ret = parse_args(argc, argv);
1151 if (ret)
1152 goto exit;
1153
1154 if (check_args(gbl_args))
1155 goto exit;
1156
1157 bench_tm_suite_init(&gbl_args->suite);
1158 gbl_args->suite.bench = test_suite;
1159 gbl_args->suite.num_bench = ODPH_ARRAY_SIZE(test_suite);
1160 gbl_args->suite.rounds = gbl_args->opt.rounds;
1161 gbl_args->suite.bench_idx = gbl_args->opt.case_idx;
1162 gbl_args->suite.measure_time = !!gbl_args->opt.time;
1163 if (common_options.is_export)
1164 gbl_args->suite.result = gbl_args->result;
1165 /* Get default worker cpumask */
1166 if (odp_cpumask_default_worker(&default_mask, 1) != 1) {
1167 ODPH_ERR("Unable to allocate worker thread\n");
1168 ret = -1;
1169 goto exit;
1170 }
1171
1172 (void)odp_cpumask_to_str(&default_mask, gbl_args->cpumask_str,
1173 sizeof(gbl_args->cpumask_str));
1174
1175 print_info(gbl_args);
1176
1177 memset(&worker_thread, 0, sizeof(odph_thread_t));
1178
1179 /* Create worker thread */
1180 cpu = odp_cpumask_first(&default_mask);
1181
1182 odp_cpumask_zero(&cpumask);
1183 odp_cpumask_set(&cpumask, cpu);
1184
1185 odph_thread_common_param_init(&thr_common);
1186 thr_common.instance = instance;
1187 thr_common.cpumask = &cpumask;
1188 thr_common.share_param = 1;
1189
1190 odph_thread_param_init(&thr_param);
1191 thr_param.start = bench_tm_run;
1192 thr_param.arg = &gbl_args->suite;
1193 thr_param.thr_type = ODP_THREAD_WORKER;
1194
1195 odph_thread_create(&worker_thread, &thr_common, &thr_param, 1);
1196
1197 odph_thread_join(&worker_thread, 1);
1198
1199 ret = gbl_args->suite.retval;
1200
1201 if (ret == 0 && common_options.is_export) {
1202 if (bench_pktio_sp_export(gbl_args)) {
1203 ODPH_ERR("Error: Export failed\n");
1204 ret = -1;
1205 }
1206 }
1207
1208exit:
1209 if (odp_shm_free(shm)) {
1210 ODPH_ERR("Shared mem free failed\n");
1211 exit(EXIT_FAILURE);
1212 }
1213
1214 if (odp_term_local()) {
1215 ODPH_ERR("Local term failed\n");
1216 exit(EXIT_FAILURE);
1217 }
1218
1219 if (odp_term_global(instance)) {
1220 ODPH_ERR("Global term failed\n");
1221 exit(EXIT_FAILURE);
1222 }
1223
1224 if (ret < 0)
1225 return EXIT_FAILURE;
1226
1227 return EXIT_SUCCESS;
1228}
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
int odp_cos_destroy(odp_cos_t cos)
Discard a class-of-service along with all its associated resources.
odp_pmr_t odp_cls_pmr_create(const odp_pmr_param_t *terms, int num_terms, odp_cos_t src_cos, odp_cos_t dst_cos)
Create Packet Matching Rule (PMR)
int odp_cls_capability(odp_cls_capability_t *capability)
Query classification capabilities.
odp_cls_pmr_term_t
Packet Matching Rule terms.
#define ODP_PMR_INVALID
Invalid packet matching rule handle.
int odp_cls_pmr_destroy(odp_pmr_t pmr)
Function to destroy a packet match rule.
#define ODP_COS_INVALID
Invalid class of service handle.
odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param)
Create a class-of-service.
void odp_cls_cos_param_init(odp_cls_cos_param_t *param)
Initialize class of service parameters.
void odp_cls_pmr_param_init(odp_pmr_param_t *param)
Initialize packet matching rule parameters.
@ ODP_PMR_TCP_DPORT
Destination TCP port (val_sz = 2)
@ ODP_PMR_TCP_SPORT
Source TCP port (val_sz = 2)
@ ODP_PMR_UDP_SPORT
Source UDP port (val_sz = 2)
@ ODP_PMR_UDP_DPORT
Destination UDP port (val_sz = 2)
#define ODP_UNUSED
Intentionally unused variables of functions.
Definition spec/hints.h:54
void odp_cpumask_set(odp_cpumask_t *mask, int cpu)
Add CPU to mask.
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
void odp_cpumask_zero(odp_cpumask_t *mask)
Clear entire CPU mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
void odp_event_free(odp_event_t event)
Free event.
#define ODP_EVENT_INVALID
Invalid event.
void odp_init_param_init(odp_init_t *param)
Initialize the odp_init_t to default values for all fields.
#define ODP_STATIC_ASSERT(cond, msg)
Compile time assertion macro.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
int odp_pktin_queue_stats(odp_pktin_queue_t queue, odp_pktin_queue_stats_t *stats)
Get statistics for direct packet input queue.
void odp_pktin_queue_param_init(odp_pktin_queue_param_t *param)
Initialize packet input queue parameters.
void odp_pktio_param_init(odp_pktio_param_t *param)
Initialize pktio params.
int odp_pktio_close(odp_pktio_t pktio)
Close a packet IO interface.
odp_pktio_t odp_pktio_lookup(const char *name)
Return a packet IO handle for an already open device.
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
Direct packet output queues.
odp_pktout_mode_t
Packet output mode.
int odp_pktin_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
Event queues for packet input.
odp_pktio_t odp_pktio_open(const char *name, odp_pool_t pool, const odp_pktio_param_t *param)
Open a packet IO interface.
int odp_pktin_event_queue_stats(odp_pktio_t pktio, odp_queue_t queue, odp_pktin_queue_stats_t *stats)
Get statistics for packet input event queue.
int odp_pktio_start(odp_pktio_t pktio)
Start packet receive and transmit.
#define ODP_PKTIO_INVALID
Invalid packet IO handle.
int odp_pktin_queue(odp_pktio_t pktio, odp_pktin_queue_t queues[], int num)
Direct packet input queues.
void odp_pktout_queue_param_init(odp_pktout_queue_param_t *param)
Initialize packet output queue parameters.
int odp_pktout_event_queue(odp_pktio_t pktio, odp_queue_t queues[], int num)
Event queues for packet output.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
int odp_pktout_event_queue_stats(odp_pktio_t pktio, odp_queue_t queue, odp_pktout_queue_stats_t *stats)
Get statistics for packet output event queue.
int odp_pktout_queue_stats(odp_pktout_queue_t queue, odp_pktout_queue_stats_t *stats)
Get statistics for direct packet output queue.
int odp_pktio_stats(odp_pktio_t pktio, odp_pktio_stats_t *stats)
Get statistics for pktio handle.
int odp_pktio_default_cos_set(odp_pktio_t pktio, odp_cos_t default_cos)
Set interface default class-of-service.
int odp_pktio_stats_reset(odp_pktio_t pktio)
Reset statistics for pktio handle.
odp_pktin_mode_t
Packet input mode.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
int odp_pktout_queue_config(odp_pktio_t pktio, const odp_pktout_queue_param_t *param)
Configure packet output queues.
@ ODP_PKTOUT_MODE_DIRECT
Direct packet output on the interface.
@ ODP_PKTOUT_MODE_QUEUE
Packet output through event queues.
@ ODP_PKTIN_MODE_DIRECT
Direct packet input from the interface.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
Queue create.
int odp_queue_destroy(odp_queue_t queue)
Destroy ODP queue.
@ ODP_QUEUE_TYPE_SCHED
Scheduled queue.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
uint64_t odp_schedule_wait_time(uint64_t ns)
Schedule wait time.
int odp_schedule_capability(odp_schedule_capability_t *capa)
Query scheduler capabilities.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
#define ODP_TIME_MSEC_IN_NS
A millisecond in nanoseconds.
The OpenDataPlane API.
Dummy type for strong typing.
Classification capabilities This capability structure defines system level classification capability.
odp_cls_pmr_terms_t supported_terms
PMR terms supported by the classifier.
uint32_t max_cos
Maximum number of CoS supported.
Class of service parameters Used to communicate class of service creation options.
odp_queue_t queue
Mapping used when num_queue = 1, hashing is disabled in this case and application has to configure th...
Global initialization parameters.
odp_mem_model_t mem_model
Application memory model.
Packet input queue parameters.
uint32_t num_queues
Number of input queues to be created.
odp_pktin_hash_proto_t hash_proto
Protocol field selection for hashing.
odp_bool_t hash_enable
Enable flow hashing.
odp_bool_t classifier_enable
Enable classifier.
Packet IO input queue specific statistics counters.
uint32_t max_input_queues
Maximum number of input queues.
uint32_t max_output_queues
Maximum number of output queues.
Packet IO parameters.
odp_pktin_mode_t in_mode
Packet input mode.
odp_pktout_mode_t out_mode
Packet output mode.
Packet IO statistics counters.
Packet output queue parameters.
uint32_t num_queues
Number of output queues to be created.
Packet IO output queue specific statistics counters.
Packet Matching Rule parameter structure.
uint32_t val_sz
Size of the value to be matched.
struct odp_pmr_param_t::@4::@6 match
Parameters for single-valued matches.
const void * value
Points to the value to be matched.
const void * mask
Mask of the bits to be matched.
odp_cls_pmr_term_t term
Packet Matching Rule term.
uint32_t max_num
Maximum number of buffers of any size.
struct odp_pool_capability_t::@134 pkt
Packet pool capabilities
uint32_t max_len
Maximum packet data length in bytes.
uint32_t num
Number of buffers in the pool.
struct odp_pool_param_t::@139 pkt
Parameters for packet pools.
odp_pool_type_t type
Pool type.
uint32_t len
Minimum length of 'num' packets.
ODP Queue parameters.
odp_queue_type_t type
Queue type.
uint32_t max_queues
Maximum number of scheduled (ODP_BLOCKING) queues of the default size.
uint64_t udp_dport
Destination UDP port, implies IPPROTO=17.
uint64_t tcp_dport
Destination TCP port implies IPPROTO=6.
struct odp_cls_pmr_terms_t::@3 bit
Packet Matching Rule term fields.
uint64_t udp_sport
Source UDP Port.
uint64_t tcp_sport
Source TCP port.
struct odp_pktin_hash_proto_t::@107 proto
Protocol header fields for hashing.
uint32_t ipv4_udp
IPv4 addresses and UDP port numbers.