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