1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #include <stdio.h> 6 #include <string.h> 7 #include <inttypes.h> 8 #include <getopt.h> 9 10 #include <rte_string_fns.h> 11 #include <rte_common.h> 12 #include <rte_eventdev.h> 13 #include <rte_lcore.h> 14 15 #include "evt_options.h" 16 #include "evt_test.h" 17 #include "parser.h" 18 19 void 20 evt_options_default(struct evt_options *opt) 21 { 22 memset(opt, 0, sizeof(*opt)); 23 opt->verbose_level = 1; /* Enable minimal prints */ 24 opt->dev_id = 0; 25 strncpy(opt->test_name, "order_queue", EVT_TEST_NAME_MAX_LEN); 26 opt->nb_flows = 1024; 27 opt->socket_id = SOCKET_ID_ANY; 28 opt->pool_sz = 16 * 1024; 29 opt->prod_enq_burst_sz = 1; 30 opt->wkr_deq_dep = 16; 31 opt->nb_pkts = (1ULL << 26); /* do ~64M packets */ 32 opt->nb_timers = 1E8; 33 opt->nb_timer_adptrs = 1; 34 opt->timer_tick_nsec = 1E3; /* 1000ns ~ 1us */ 35 opt->max_tmo_nsec = 1E5; /* 100000ns ~100us */ 36 opt->expiry_nsec = 1E4; /* 10000ns ~10us */ 37 opt->prod_type = EVT_PROD_TYPE_SYNT; 38 opt->eth_queues = 1; 39 opt->vector_size = 64; 40 opt->vector_tmo_nsec = 100E3; 41 opt->crypto_op_type = RTE_CRYPTO_OP_TYPE_SYMMETRIC; 42 } 43 44 typedef int (*option_parser_t)(struct evt_options *opt, 45 const char *arg); 46 47 struct long_opt_parser { 48 const char *lgopt_name; 49 option_parser_t parser_fn; 50 }; 51 52 static int 53 evt_parse_nb_flows(struct evt_options *opt, const char *arg) 54 { 55 int ret; 56 57 ret = parser_read_uint32(&(opt->nb_flows), arg); 58 59 return ret; 60 } 61 62 static int 63 evt_parse_dev_id(struct evt_options *opt, const char *arg) 64 { 65 int ret; 66 67 ret = parser_read_uint8(&(opt->dev_id), arg); 68 69 return ret; 70 } 71 72 static int 73 evt_parse_verbose(struct evt_options *opt, const char *arg __rte_unused) 74 { 75 opt->verbose_level = atoi(arg); 76 return 0; 77 } 78 79 static int 80 evt_parse_fwd_latency(struct evt_options *opt, const char *arg __rte_unused) 81 { 82 opt->fwd_latency = 1; 83 return 0; 84 } 85 86 static int 87 evt_parse_queue_priority(struct evt_options *opt, const char *arg __rte_unused) 88 { 89 opt->q_priority = 1; 90 return 0; 91 } 92 93 static int 94 evt_parse_deq_tmo_nsec(struct evt_options *opt, const char *arg) 95 { 96 int ret; 97 98 ret = parser_read_uint32(&(opt->deq_tmo_nsec), arg); 99 100 return ret; 101 } 102 103 static int 104 evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused) 105 { 106 opt->prod_type = EVT_PROD_TYPE_ETH_RX_ADPTR; 107 return 0; 108 } 109 110 static int 111 evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused) 112 { 113 opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR; 114 return 0; 115 } 116 117 static int 118 evt_parse_timer_prod_type_burst(struct evt_options *opt, 119 const char *arg __rte_unused) 120 { 121 opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR; 122 opt->timdev_use_burst = 1; 123 return 0; 124 } 125 126 static int 127 evt_parse_crypto_prod_type(struct evt_options *opt, 128 const char *arg __rte_unused) 129 { 130 opt->prod_type = EVT_PROD_TYPE_EVENT_CRYPTO_ADPTR; 131 return 0; 132 } 133 134 static int 135 evt_parse_crypto_adptr_mode(struct evt_options *opt, const char *arg) 136 { 137 uint8_t mode; 138 int ret; 139 140 ret = parser_read_uint8(&mode, arg); 141 opt->crypto_adptr_mode = mode ? RTE_EVENT_CRYPTO_ADAPTER_OP_FORWARD : 142 RTE_EVENT_CRYPTO_ADAPTER_OP_NEW; 143 return ret; 144 } 145 146 static int 147 evt_parse_crypto_op_type(struct evt_options *opt, const char *arg) 148 { 149 uint8_t op_type; 150 int ret; 151 152 ret = parser_read_uint8(&op_type, arg); 153 opt->crypto_op_type = op_type ? RTE_CRYPTO_OP_TYPE_ASYMMETRIC : 154 RTE_CRYPTO_OP_TYPE_SYMMETRIC; 155 return ret; 156 } 157 158 static int 159 evt_parse_test_name(struct evt_options *opt, const char *arg) 160 { 161 strlcpy(opt->test_name, arg, EVT_TEST_NAME_MAX_LEN); 162 return 0; 163 } 164 165 static int 166 evt_parse_socket_id(struct evt_options *opt, const char *arg) 167 { 168 opt->socket_id = atoi(arg); 169 return 0; 170 } 171 172 static int 173 evt_parse_wkr_deq_dep(struct evt_options *opt, const char *arg) 174 { 175 int ret; 176 177 ret = parser_read_uint16(&(opt->wkr_deq_dep), arg); 178 return ret; 179 } 180 181 static int 182 evt_parse_nb_pkts(struct evt_options *opt, const char *arg) 183 { 184 int ret; 185 186 ret = parser_read_uint64(&(opt->nb_pkts), arg); 187 188 return ret; 189 } 190 191 static int 192 evt_parse_nb_timers(struct evt_options *opt, const char *arg) 193 { 194 int ret; 195 196 ret = parser_read_uint64(&(opt->nb_timers), arg); 197 198 return ret; 199 } 200 201 static int 202 evt_parse_timer_tick_nsec(struct evt_options *opt, const char *arg) 203 { 204 int ret; 205 206 ret = parser_read_uint64(&(opt->timer_tick_nsec), arg); 207 208 return ret; 209 } 210 211 static int 212 evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg) 213 { 214 int ret; 215 216 ret = parser_read_uint64(&(opt->max_tmo_nsec), arg); 217 218 return ret; 219 } 220 221 static int 222 evt_parse_expiry_nsec(struct evt_options *opt, const char *arg) 223 { 224 int ret; 225 226 ret = parser_read_uint64(&(opt->expiry_nsec), arg); 227 228 return ret; 229 } 230 231 static int 232 evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg) 233 { 234 int ret; 235 236 ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg); 237 if (opt->nb_timer_adptrs <= 0) { 238 evt_err("Number of timer adapters cannot be <= 0"); 239 return -EINVAL; 240 } 241 242 return ret; 243 } 244 245 static int 246 evt_parse_pool_sz(struct evt_options *opt, const char *arg) 247 { 248 opt->pool_sz = atoi(arg); 249 250 return 0; 251 } 252 253 static int 254 evt_parse_plcores(struct evt_options *opt, const char *corelist) 255 { 256 int ret; 257 258 ret = parse_lcores_list(opt->plcores, RTE_MAX_LCORE, corelist); 259 if (ret == -E2BIG) 260 evt_err("duplicate lcores in plcores"); 261 262 return ret; 263 } 264 265 static int 266 evt_parse_work_lcores(struct evt_options *opt, const char *corelist) 267 { 268 int ret; 269 270 ret = parse_lcores_list(opt->wlcores, RTE_MAX_LCORE, corelist); 271 if (ret == -E2BIG) 272 evt_err("duplicate lcores in wlcores"); 273 274 return ret; 275 } 276 277 static int 278 evt_parse_mbuf_sz(struct evt_options *opt, const char *arg) 279 { 280 int ret; 281 282 ret = parser_read_uint16(&(opt->mbuf_sz), arg); 283 284 return ret; 285 } 286 287 static int 288 evt_parse_max_pkt_sz(struct evt_options *opt, const char *arg) 289 { 290 int ret; 291 292 ret = parser_read_uint32(&(opt->max_pkt_sz), arg); 293 294 return ret; 295 } 296 297 static int 298 evt_parse_ena_vector(struct evt_options *opt, const char *arg __rte_unused) 299 { 300 opt->ena_vector = 1; 301 return 0; 302 } 303 304 static int 305 evt_parse_vector_size(struct evt_options *opt, const char *arg) 306 { 307 int ret; 308 309 ret = parser_read_uint16(&(opt->vector_size), arg); 310 311 return ret; 312 } 313 314 static int 315 evt_parse_vector_tmo_ns(struct evt_options *opt, const char *arg) 316 { 317 int ret; 318 319 ret = parser_read_uint64(&(opt->vector_tmo_nsec), arg); 320 321 return ret; 322 } 323 324 static int 325 evt_parse_eth_queues(struct evt_options *opt, const char *arg) 326 { 327 int ret; 328 329 ret = parser_read_uint16(&(opt->eth_queues), arg); 330 331 return ret; 332 } 333 334 static int 335 evt_parse_per_port_pool(struct evt_options *opt, const char *arg __rte_unused) 336 { 337 opt->per_port_pool = 1; 338 return 0; 339 } 340 341 static int 342 evt_parse_prod_enq_burst_sz(struct evt_options *opt, const char *arg) 343 { 344 int ret; 345 346 ret = parser_read_uint32(&(opt->prod_enq_burst_sz), arg); 347 348 return ret; 349 } 350 351 static void 352 usage(char *program) 353 { 354 printf("usage : %s [EAL options] -- [application options]\n", program); 355 printf("application options:\n"); 356 printf("\t--verbose : verbose level\n" 357 "\t--dev : device id of the event device\n" 358 "\t--test : name of the test application to run\n" 359 "\t--socket_id : socket_id of application resources\n" 360 "\t--pool_sz : pool size of the mempool\n" 361 "\t--plcores : list of lcore ids for producers\n" 362 "\t--wlcores : list of lcore ids for workers\n" 363 "\t--stlist : list of scheduled types of the stages\n" 364 "\t--nb_flows : number of flows to produce\n" 365 "\t--nb_pkts : number of packets to produce\n" 366 "\t--worker_deq_depth : dequeue depth of the worker\n" 367 "\t--fwd_latency : perform fwd_latency measurement\n" 368 "\t--queue_priority : enable queue priority\n" 369 "\t--deq_tmo_nsec : global dequeue timeout\n" 370 "\t--prod_type_ethdev : use ethernet device as producer.\n" 371 "\t--prod_type_cryptodev : use crypto device as producer.\n" 372 "\t--prod_type_timerdev : use event timer device as producer.\n" 373 "\t expiry_nsec would be the timeout\n" 374 "\t in ns.\n" 375 "\t--prod_type_timerdev_burst : use timer device as producer\n" 376 "\t burst mode.\n" 377 "\t--nb_timers : number of timers to arm.\n" 378 "\t--nb_timer_adptrs : number of timer adapters to use.\n" 379 "\t--timer_tick_nsec : timer tick interval in ns.\n" 380 "\t--max_tmo_nsec : max timeout interval in ns.\n" 381 "\t--expiry_nsec : event timer expiry ns.\n" 382 "\t--crypto_adptr_mode : 0 for OP_NEW mode (default) and\n" 383 "\t 1 for OP_FORWARD mode.\n" 384 "\t--crypto_op_type : 0 for SYM ops (default) and\n" 385 "\t 1 for ASYM ops.\n" 386 "\t--mbuf_sz : packet mbuf size.\n" 387 "\t--max_pkt_sz : max packet size.\n" 388 "\t--prod_enq_burst_sz : producer enqueue burst size.\n" 389 "\t--nb_eth_queues : number of ethernet Rx queues.\n" 390 "\t--enable_vector : enable event vectorization.\n" 391 "\t--vector_size : Max vector size.\n" 392 "\t--vector_tmo_ns : Max vector timeout in nanoseconds\n" 393 "\t--per_port_pool : Configure unique pool per ethdev port\n" 394 ); 395 printf("available tests:\n"); 396 evt_test_dump_names(); 397 } 398 399 static int 400 evt_parse_sched_type_list(struct evt_options *opt, const char *arg) 401 { 402 char c; 403 int i = 0, j = -1; 404 405 for (i = 0; i < EVT_MAX_STAGES; i++) 406 opt->sched_type_list[i] = (uint8_t)-1; 407 408 i = 0; 409 410 do { 411 c = arg[++j]; 412 413 switch (c) { 414 case 'o': 415 case 'O': 416 opt->sched_type_list[i++] = RTE_SCHED_TYPE_ORDERED; 417 break; 418 case 'a': 419 case 'A': 420 opt->sched_type_list[i++] = RTE_SCHED_TYPE_ATOMIC; 421 break; 422 case 'p': 423 case 'P': 424 opt->sched_type_list[i++] = RTE_SCHED_TYPE_PARALLEL; 425 break; 426 case ',': 427 break; 428 default: 429 if (c != '\0') { 430 evt_err("invalid sched_type %c", c); 431 return -EINVAL; 432 } 433 } 434 } while (c != '\0'); 435 436 opt->nb_stages = i; 437 return 0; 438 } 439 440 static struct option lgopts[] = { 441 { EVT_NB_FLOWS, 1, 0, 0 }, 442 { EVT_DEVICE, 1, 0, 0 }, 443 { EVT_VERBOSE, 1, 0, 0 }, 444 { EVT_TEST, 1, 0, 0 }, 445 { EVT_PROD_LCORES, 1, 0, 0 }, 446 { EVT_WORK_LCORES, 1, 0, 0 }, 447 { EVT_SOCKET_ID, 1, 0, 0 }, 448 { EVT_POOL_SZ, 1, 0, 0 }, 449 { EVT_NB_PKTS, 1, 0, 0 }, 450 { EVT_WKR_DEQ_DEP, 1, 0, 0 }, 451 { EVT_SCHED_TYPE_LIST, 1, 0, 0 }, 452 { EVT_FWD_LATENCY, 0, 0, 0 }, 453 { EVT_QUEUE_PRIORITY, 0, 0, 0 }, 454 { EVT_DEQ_TMO_NSEC, 1, 0, 0 }, 455 { EVT_PROD_ETHDEV, 0, 0, 0 }, 456 { EVT_PROD_CRYPTODEV, 0, 0, 0 }, 457 { EVT_PROD_TIMERDEV, 0, 0, 0 }, 458 { EVT_PROD_TIMERDEV_BURST, 0, 0, 0 }, 459 { EVT_CRYPTO_ADPTR_MODE, 1, 0, 0 }, 460 { EVT_CRYPTO_OP_TYPE, 1, 0, 0 }, 461 { EVT_NB_TIMERS, 1, 0, 0 }, 462 { EVT_NB_TIMER_ADPTRS, 1, 0, 0 }, 463 { EVT_TIMER_TICK_NSEC, 1, 0, 0 }, 464 { EVT_MAX_TMO_NSEC, 1, 0, 0 }, 465 { EVT_EXPIRY_NSEC, 1, 0, 0 }, 466 { EVT_MBUF_SZ, 1, 0, 0 }, 467 { EVT_MAX_PKT_SZ, 1, 0, 0 }, 468 { EVT_PROD_ENQ_BURST_SZ, 1, 0, 0 }, 469 { EVT_NB_ETH_QUEUES, 1, 0, 0 }, 470 { EVT_ENA_VECTOR, 0, 0, 0 }, 471 { EVT_VECTOR_SZ, 1, 0, 0 }, 472 { EVT_VECTOR_TMO, 1, 0, 0 }, 473 { EVT_PER_PORT_POOL, 0, 0, 0 }, 474 { EVT_HELP, 0, 0, 0 }, 475 { NULL, 0, 0, 0 } 476 }; 477 478 static int 479 evt_opts_parse_long(int opt_idx, struct evt_options *opt) 480 { 481 unsigned int i; 482 483 struct long_opt_parser parsermap[] = { 484 { EVT_NB_FLOWS, evt_parse_nb_flows}, 485 { EVT_DEVICE, evt_parse_dev_id}, 486 { EVT_VERBOSE, evt_parse_verbose}, 487 { EVT_TEST, evt_parse_test_name}, 488 { EVT_PROD_LCORES, evt_parse_plcores}, 489 { EVT_WORK_LCORES, evt_parse_work_lcores}, 490 { EVT_SOCKET_ID, evt_parse_socket_id}, 491 { EVT_POOL_SZ, evt_parse_pool_sz}, 492 { EVT_NB_PKTS, evt_parse_nb_pkts}, 493 { EVT_WKR_DEQ_DEP, evt_parse_wkr_deq_dep}, 494 { EVT_SCHED_TYPE_LIST, evt_parse_sched_type_list}, 495 { EVT_FWD_LATENCY, evt_parse_fwd_latency}, 496 { EVT_QUEUE_PRIORITY, evt_parse_queue_priority}, 497 { EVT_DEQ_TMO_NSEC, evt_parse_deq_tmo_nsec}, 498 { EVT_PROD_ETHDEV, evt_parse_eth_prod_type}, 499 { EVT_PROD_CRYPTODEV, evt_parse_crypto_prod_type}, 500 { EVT_PROD_TIMERDEV, evt_parse_timer_prod_type}, 501 { EVT_PROD_TIMERDEV_BURST, evt_parse_timer_prod_type_burst}, 502 { EVT_CRYPTO_ADPTR_MODE, evt_parse_crypto_adptr_mode}, 503 { EVT_CRYPTO_OP_TYPE, evt_parse_crypto_op_type}, 504 { EVT_NB_TIMERS, evt_parse_nb_timers}, 505 { EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs}, 506 { EVT_TIMER_TICK_NSEC, evt_parse_timer_tick_nsec}, 507 { EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec}, 508 { EVT_EXPIRY_NSEC, evt_parse_expiry_nsec}, 509 { EVT_MBUF_SZ, evt_parse_mbuf_sz}, 510 { EVT_MAX_PKT_SZ, evt_parse_max_pkt_sz}, 511 { EVT_PROD_ENQ_BURST_SZ, evt_parse_prod_enq_burst_sz}, 512 { EVT_NB_ETH_QUEUES, evt_parse_eth_queues}, 513 { EVT_ENA_VECTOR, evt_parse_ena_vector}, 514 { EVT_VECTOR_SZ, evt_parse_vector_size}, 515 { EVT_VECTOR_TMO, evt_parse_vector_tmo_ns}, 516 { EVT_PER_PORT_POOL, evt_parse_per_port_pool}, 517 }; 518 519 for (i = 0; i < RTE_DIM(parsermap); i++) { 520 if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name, 521 strlen(lgopts[opt_idx].name)) == 0) 522 return parsermap[i].parser_fn(opt, optarg); 523 } 524 525 return -EINVAL; 526 } 527 528 int 529 evt_options_parse(struct evt_options *opt, int argc, char **argv) 530 { 531 int opts, retval, opt_idx; 532 533 while ((opts = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) { 534 switch (opts) { 535 case 0: /* long options */ 536 if (!strcmp(lgopts[opt_idx].name, "help")) { 537 usage(argv[0]); 538 exit(EXIT_SUCCESS); 539 } 540 541 retval = evt_opts_parse_long(opt_idx, opt); 542 if (retval != 0) 543 return retval; 544 break; 545 default: 546 return -EINVAL; 547 } 548 } 549 return 0; 550 } 551 552 void 553 evt_options_dump(struct evt_options *opt) 554 { 555 int lcore_id; 556 struct rte_event_dev_info dev_info; 557 558 rte_event_dev_info_get(opt->dev_id, &dev_info); 559 evt_dump("driver", "%s", dev_info.driver_name); 560 evt_dump("test", "%s", opt->test_name); 561 evt_dump("dev", "%d", opt->dev_id); 562 evt_dump("verbose_level", "%d", opt->verbose_level); 563 evt_dump("socket_id", "%d", opt->socket_id); 564 evt_dump("pool_sz", "%d", opt->pool_sz); 565 evt_dump("main lcore", "%d", rte_get_main_lcore()); 566 evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts); 567 evt_dump("nb_timers", "%"PRIu64, opt->nb_timers); 568 evt_dump_begin("available lcores"); 569 RTE_LCORE_FOREACH(lcore_id) 570 printf("%d ", lcore_id); 571 evt_dump_end; 572 evt_dump_nb_flows(opt); 573 evt_dump_worker_dequeue_depth(opt); 574 } 575