xref: /dpdk/app/test-eventdev/evt_options.c (revision 25d11a86c56d50947af33d0b79ede622809bd8b9)
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_common.h>
11 #include <rte_eventdev.h>
12 #include <rte_lcore.h>
13 
14 #include "evt_options.h"
15 #include "evt_test.h"
16 #include "parser.h"
17 
18 void
19 evt_options_default(struct evt_options *opt)
20 {
21 	memset(opt, 0, sizeof(*opt));
22 	opt->verbose_level = 1; /* Enable minimal prints */
23 	opt->dev_id = 0;
24 	strncpy(opt->test_name, "order_queue", EVT_TEST_NAME_MAX_LEN);
25 	opt->nb_flows = 1024;
26 	opt->socket_id = SOCKET_ID_ANY;
27 	opt->pool_sz = 16 * 1024;
28 	opt->wkr_deq_dep = 16;
29 	opt->nb_pkts = (1ULL << 26); /* do ~64M packets */
30 	opt->nb_timers = 1E8;
31 	opt->nb_timer_adptrs = 1;
32 	opt->timer_tick_nsec = 1E3; /* 1000ns ~ 1us */
33 	opt->max_tmo_nsec = 1E5;  /* 100000ns ~100us */
34 	opt->expiry_nsec = 1E4;   /* 10000ns ~10us */
35 	opt->prod_type = EVT_PROD_TYPE_SYNT;
36 }
37 
38 typedef int (*option_parser_t)(struct evt_options *opt,
39 		const char *arg);
40 
41 struct long_opt_parser {
42 	const char *lgopt_name;
43 	option_parser_t parser_fn;
44 };
45 
46 static int
47 evt_parse_nb_flows(struct evt_options *opt, const char *arg)
48 {
49 	int ret;
50 
51 	ret = parser_read_uint32(&(opt->nb_flows), arg);
52 
53 	return ret;
54 }
55 
56 static int
57 evt_parse_dev_id(struct evt_options *opt, const char *arg)
58 {
59 	int ret;
60 
61 	ret = parser_read_uint8(&(opt->dev_id), arg);
62 
63 	return ret;
64 }
65 
66 static int
67 evt_parse_verbose(struct evt_options *opt, const char *arg __rte_unused)
68 {
69 	opt->verbose_level = atoi(arg);
70 	return 0;
71 }
72 
73 static int
74 evt_parse_fwd_latency(struct evt_options *opt, const char *arg __rte_unused)
75 {
76 	opt->fwd_latency = 1;
77 	return 0;
78 }
79 
80 static int
81 evt_parse_queue_priority(struct evt_options *opt, const char *arg __rte_unused)
82 {
83 	opt->q_priority = 1;
84 	return 0;
85 }
86 
87 static int
88 evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
89 {
90 	opt->prod_type = EVT_PROD_TYPE_ETH_RX_ADPTR;
91 	return 0;
92 }
93 
94 static int
95 evt_parse_timer_prod_type(struct evt_options *opt, const char *arg __rte_unused)
96 {
97 	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
98 	return 0;
99 }
100 
101 static int
102 evt_parse_timer_prod_type_burst(struct evt_options *opt,
103 		const char *arg __rte_unused)
104 {
105 	opt->prod_type = EVT_PROD_TYPE_EVENT_TIMER_ADPTR;
106 	opt->timdev_use_burst = 1;
107 	return 0;
108 }
109 
110 static int
111 evt_parse_test_name(struct evt_options *opt, const char *arg)
112 {
113 	snprintf(opt->test_name, EVT_TEST_NAME_MAX_LEN, "%s", arg);
114 	return 0;
115 }
116 
117 static int
118 evt_parse_socket_id(struct evt_options *opt, const char *arg)
119 {
120 	opt->socket_id = atoi(arg);
121 	return 0;
122 }
123 
124 static int
125 evt_parse_wkr_deq_dep(struct evt_options *opt, const char *arg)
126 {
127 	int ret;
128 
129 	ret = parser_read_uint16(&(opt->wkr_deq_dep), arg);
130 	return ret;
131 }
132 
133 static int
134 evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
135 {
136 	int ret;
137 
138 	ret = parser_read_uint64(&(opt->nb_pkts), arg);
139 
140 	return ret;
141 }
142 
143 static int
144 evt_parse_nb_timers(struct evt_options *opt, const char *arg)
145 {
146 	int ret;
147 
148 	ret = parser_read_uint64(&(opt->nb_timers), arg);
149 
150 	return ret;
151 }
152 
153 static int
154 evt_parse_timer_tick_nsec(struct evt_options *opt, const char *arg)
155 {
156 	int ret;
157 
158 	ret = parser_read_uint64(&(opt->timer_tick_nsec), arg);
159 
160 	return ret;
161 }
162 
163 static int
164 evt_parse_max_tmo_nsec(struct evt_options *opt, const char *arg)
165 {
166 	int ret;
167 
168 	ret = parser_read_uint64(&(opt->max_tmo_nsec), arg);
169 
170 	return ret;
171 }
172 
173 static int
174 evt_parse_expiry_nsec(struct evt_options *opt, const char *arg)
175 {
176 	int ret;
177 
178 	ret = parser_read_uint64(&(opt->expiry_nsec), arg);
179 
180 	return ret;
181 }
182 
183 static int
184 evt_parse_nb_timer_adptrs(struct evt_options *opt, const char *arg)
185 {
186 	int ret;
187 
188 	ret = parser_read_uint8(&(opt->nb_timer_adptrs), arg);
189 
190 	return ret;
191 }
192 
193 static int
194 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
195 {
196 	opt->pool_sz = atoi(arg);
197 
198 	return 0;
199 }
200 
201 static int
202 evt_parse_plcores(struct evt_options *opt, const char *corelist)
203 {
204 	int ret;
205 
206 	ret = parse_lcores_list(opt->plcores, corelist);
207 	if (ret == -E2BIG)
208 		evt_err("duplicate lcores in plcores");
209 
210 	return ret;
211 }
212 
213 static int
214 evt_parse_work_lcores(struct evt_options *opt, const char *corelist)
215 {
216 	int ret;
217 
218 	ret = parse_lcores_list(opt->wlcores, corelist);
219 	if (ret == -E2BIG)
220 		evt_err("duplicate lcores in wlcores");
221 
222 	return ret;
223 }
224 
225 static void
226 usage(char *program)
227 {
228 	printf("usage : %s [EAL options] -- [application options]\n", program);
229 	printf("application options:\n");
230 	printf("\t--verbose          : verbose level\n"
231 		"\t--dev              : device id of the event device\n"
232 		"\t--test             : name of the test application to run\n"
233 		"\t--socket_id        : socket_id of application resources\n"
234 		"\t--pool_sz          : pool size of the mempool\n"
235 		"\t--plcores          : list of lcore ids for producers\n"
236 		"\t--wlcores          : list of lcore ids for workers\n"
237 		"\t--stlist           : list of scheduled types of the stages\n"
238 		"\t--nb_flows         : number of flows to produce\n"
239 		"\t--nb_pkts          : number of packets to produce\n"
240 		"\t--worker_deq_depth : dequeue depth of the worker\n"
241 		"\t--fwd_latency      : perform fwd_latency measurement\n"
242 		"\t--queue_priority   : enable queue priority\n"
243 		"\t--prod_type_ethdev : use ethernet device as producer.\n"
244 		"\t--prod_type_timerdev : use event timer device as producer.\n"
245 		"\t                     expity_nsec would be the timeout\n"
246 		"\t                     in ns.\n"
247 		"\t--prod_type_timerdev_burst : use timer device as producer\n"
248 		"\t                             burst mode.\n"
249 		"\t--nb_timers        : number of timers to arm.\n"
250 		"\t--nb_timer_adptrs  : number of timer adapters to use.\n"
251 		"\t--timer_tick_nsec  : timer tick interval in ns.\n"
252 		"\t--max_tmo_nsec     : max timeout interval in ns.\n"
253 		"\t--expiry_nsec        : event timer expiry ns.\n"
254 		);
255 	printf("available tests:\n");
256 	evt_test_dump_names();
257 }
258 
259 static int
260 evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
261 {
262 	char c;
263 	int i = 0, j = -1;
264 
265 	for (i = 0; i < EVT_MAX_STAGES; i++)
266 		opt->sched_type_list[i] = (uint8_t)-1;
267 
268 	i = 0;
269 
270 	do {
271 		c = arg[++j];
272 
273 		switch (c) {
274 		case 'o':
275 		case 'O':
276 			opt->sched_type_list[i++] = RTE_SCHED_TYPE_ORDERED;
277 			break;
278 		case 'a':
279 		case 'A':
280 			opt->sched_type_list[i++] = RTE_SCHED_TYPE_ATOMIC;
281 			break;
282 		case 'p':
283 		case 'P':
284 			opt->sched_type_list[i++] = RTE_SCHED_TYPE_PARALLEL;
285 			break;
286 		case ',':
287 			break;
288 		default:
289 			if (c != '\0') {
290 				evt_err("invalid sched_type %c", c);
291 				return -EINVAL;
292 			}
293 		}
294 	} while (c != '\0');
295 
296 	opt->nb_stages = i;
297 	return 0;
298 }
299 
300 static struct option lgopts[] = {
301 	{ EVT_NB_FLOWS,            1, 0, 0 },
302 	{ EVT_DEVICE,              1, 0, 0 },
303 	{ EVT_VERBOSE,             1, 0, 0 },
304 	{ EVT_TEST,                1, 0, 0 },
305 	{ EVT_PROD_LCORES,         1, 0, 0 },
306 	{ EVT_WORK_LCORES,         1, 0, 0 },
307 	{ EVT_SOCKET_ID,           1, 0, 0 },
308 	{ EVT_POOL_SZ,             1, 0, 0 },
309 	{ EVT_NB_PKTS,             1, 0, 0 },
310 	{ EVT_WKR_DEQ_DEP,         1, 0, 0 },
311 	{ EVT_SCHED_TYPE_LIST,     1, 0, 0 },
312 	{ EVT_FWD_LATENCY,         0, 0, 0 },
313 	{ EVT_QUEUE_PRIORITY,      0, 0, 0 },
314 	{ EVT_PROD_ETHDEV,         0, 0, 0 },
315 	{ EVT_PROD_TIMERDEV,       0, 0, 0 },
316 	{ EVT_PROD_TIMERDEV_BURST, 0, 0, 0 },
317 	{ EVT_NB_TIMERS,           1, 0, 0 },
318 	{ EVT_NB_TIMER_ADPTRS,     1, 0, 0 },
319 	{ EVT_TIMER_TICK_NSEC,     1, 0, 0 },
320 	{ EVT_MAX_TMO_NSEC,        1, 0, 0 },
321 	{ EVT_EXPIRY_NSEC,         1, 0, 0 },
322 	{ EVT_HELP,                0, 0, 0 },
323 	{ NULL,                    0, 0, 0 }
324 };
325 
326 static int
327 evt_opts_parse_long(int opt_idx, struct evt_options *opt)
328 {
329 	unsigned int i;
330 
331 	struct long_opt_parser parsermap[] = {
332 		{ EVT_NB_FLOWS, evt_parse_nb_flows},
333 		{ EVT_DEVICE, evt_parse_dev_id},
334 		{ EVT_VERBOSE, evt_parse_verbose},
335 		{ EVT_TEST, evt_parse_test_name},
336 		{ EVT_PROD_LCORES, evt_parse_plcores},
337 		{ EVT_WORK_LCORES, evt_parse_work_lcores},
338 		{ EVT_SOCKET_ID, evt_parse_socket_id},
339 		{ EVT_POOL_SZ, evt_parse_pool_sz},
340 		{ EVT_NB_PKTS, evt_parse_nb_pkts},
341 		{ EVT_WKR_DEQ_DEP, evt_parse_wkr_deq_dep},
342 		{ EVT_SCHED_TYPE_LIST, evt_parse_sched_type_list},
343 		{ EVT_FWD_LATENCY, evt_parse_fwd_latency},
344 		{ EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
345 		{ EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
346 		{ EVT_PROD_TIMERDEV, evt_parse_timer_prod_type},
347 		{ EVT_PROD_TIMERDEV_BURST, evt_parse_timer_prod_type_burst},
348 		{ EVT_NB_TIMERS, evt_parse_nb_timers},
349 		{ EVT_NB_TIMER_ADPTRS, evt_parse_nb_timer_adptrs},
350 		{ EVT_TIMER_TICK_NSEC, evt_parse_timer_tick_nsec},
351 		{ EVT_MAX_TMO_NSEC, evt_parse_max_tmo_nsec},
352 		{ EVT_EXPIRY_NSEC, evt_parse_expiry_nsec},
353 	};
354 
355 	for (i = 0; i < RTE_DIM(parsermap); i++) {
356 		if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
357 				strlen(lgopts[opt_idx].name)) == 0)
358 			return parsermap[i].parser_fn(opt, optarg);
359 	}
360 
361 	return -EINVAL;
362 }
363 
364 int
365 evt_options_parse(struct evt_options *opt, int argc, char **argv)
366 {
367 	int opts, retval, opt_idx;
368 
369 	while ((opts = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) {
370 		switch (opts) {
371 		case 0: /* long options */
372 			if (!strcmp(lgopts[opt_idx].name, "help")) {
373 				usage(argv[0]);
374 				exit(EXIT_SUCCESS);
375 			}
376 
377 			retval = evt_opts_parse_long(opt_idx, opt);
378 			if (retval != 0)
379 				return retval;
380 			break;
381 		default:
382 			return -EINVAL;
383 		}
384 	}
385 	return 0;
386 }
387 
388 void
389 evt_options_dump(struct evt_options *opt)
390 {
391 	int lcore_id;
392 	struct rte_event_dev_info dev_info;
393 
394 	rte_event_dev_info_get(opt->dev_id, &dev_info);
395 	evt_dump("driver", "%s", dev_info.driver_name);
396 	evt_dump("test", "%s", opt->test_name);
397 	evt_dump("dev", "%d", opt->dev_id);
398 	evt_dump("verbose_level", "%d", opt->verbose_level);
399 	evt_dump("socket_id", "%d", opt->socket_id);
400 	evt_dump("pool_sz", "%d", opt->pool_sz);
401 	evt_dump("master lcore", "%d", rte_get_master_lcore());
402 	evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
403 	evt_dump("nb_timers", "%"PRIu64, opt->nb_timers);
404 	evt_dump_begin("available lcores");
405 	RTE_LCORE_FOREACH(lcore_id)
406 		printf("%d ", lcore_id);
407 	evt_dump_end;
408 	evt_dump_nb_flows(opt);
409 	evt_dump_worker_dequeue_depth(opt);
410 }
411