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