New upstream version 18.02
[deb_dpdk.git] / app / test-eventdev / evt_options.c
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->prod_type = EVT_PROD_TYPE_SYNT;
31 }
32
33 typedef int (*option_parser_t)(struct evt_options *opt,
34                 const char *arg);
35
36 struct long_opt_parser {
37         const char *lgopt_name;
38         option_parser_t parser_fn;
39 };
40
41 static int
42 evt_parse_nb_flows(struct evt_options *opt, const char *arg)
43 {
44         int ret;
45
46         ret = parser_read_uint32(&(opt->nb_flows), arg);
47
48         return ret;
49 }
50
51 static int
52 evt_parse_dev_id(struct evt_options *opt, const char *arg)
53 {
54         int ret;
55
56         ret = parser_read_uint8(&(opt->dev_id), arg);
57
58         return ret;
59 }
60
61 static int
62 evt_parse_verbose(struct evt_options *opt, const char *arg __rte_unused)
63 {
64         opt->verbose_level = atoi(arg);
65         return 0;
66 }
67
68 static int
69 evt_parse_fwd_latency(struct evt_options *opt, const char *arg __rte_unused)
70 {
71         opt->fwd_latency = 1;
72         return 0;
73 }
74
75 static int
76 evt_parse_queue_priority(struct evt_options *opt, const char *arg __rte_unused)
77 {
78         opt->q_priority = 1;
79         return 0;
80 }
81
82 static int
83 evt_parse_eth_prod_type(struct evt_options *opt, const char *arg __rte_unused)
84 {
85         opt->prod_type = EVT_PROD_TYPE_ETH_RX_ADPTR;
86         return 0;
87 }
88
89 static int
90 evt_parse_test_name(struct evt_options *opt, const char *arg)
91 {
92         snprintf(opt->test_name, EVT_TEST_NAME_MAX_LEN, "%s", arg);
93         return 0;
94 }
95
96 static int
97 evt_parse_socket_id(struct evt_options *opt, const char *arg)
98 {
99         opt->socket_id = atoi(arg);
100         return 0;
101 }
102
103 static int
104 evt_parse_wkr_deq_dep(struct evt_options *opt, const char *arg)
105 {
106         int ret;
107
108         ret = parser_read_uint16(&(opt->wkr_deq_dep), arg);
109         return ret;
110 }
111
112 static int
113 evt_parse_nb_pkts(struct evt_options *opt, const char *arg)
114 {
115         int ret;
116
117         ret = parser_read_uint64(&(opt->nb_pkts), arg);
118
119         return ret;
120 }
121
122 static int
123 evt_parse_pool_sz(struct evt_options *opt, const char *arg)
124 {
125         opt->pool_sz = atoi(arg);
126
127         return 0;
128 }
129
130 static int
131 evt_parse_plcores(struct evt_options *opt, const char *corelist)
132 {
133         int ret;
134
135         ret = parse_lcores_list(opt->plcores, corelist);
136         if (ret == -E2BIG)
137                 evt_err("duplicate lcores in plcores");
138
139         return ret;
140 }
141
142 static int
143 evt_parse_work_lcores(struct evt_options *opt, const char *corelist)
144 {
145         int ret;
146
147         ret = parse_lcores_list(opt->wlcores, corelist);
148         if (ret == -E2BIG)
149                 evt_err("duplicate lcores in wlcores");
150
151         return ret;
152 }
153
154 static void
155 usage(char *program)
156 {
157         printf("usage : %s [EAL options] -- [application options]\n", program);
158         printf("application options:\n");
159         printf("\t--verbose          : verbose level\n"
160                 "\t--dev              : device id of the event device\n"
161                 "\t--test             : name of the test application to run\n"
162                 "\t--socket_id        : socket_id of application resources\n"
163                 "\t--pool_sz          : pool size of the mempool\n"
164                 "\t--plcores          : list of lcore ids for producers\n"
165                 "\t--wlcores          : list of lcore ids for workers\n"
166                 "\t--stlist           : list of scheduled types of the stages\n"
167                 "\t--nb_flows         : number of flows to produce\n"
168                 "\t--nb_pkts          : number of packets to produce\n"
169                 "\t--worker_deq_depth : dequeue depth of the worker\n"
170                 "\t--fwd_latency      : perform fwd_latency measurement\n"
171                 "\t--queue_priority   : enable queue priority\n"
172                 "\t--prod_type_ethdev : use ethernet device as producer\n."
173                 );
174         printf("available tests:\n");
175         evt_test_dump_names();
176 }
177
178 static int
179 evt_parse_sched_type_list(struct evt_options *opt, const char *arg)
180 {
181         char c;
182         int i = 0, j = -1;
183
184         for (i = 0; i < EVT_MAX_STAGES; i++)
185                 opt->sched_type_list[i] = (uint8_t)-1;
186
187         i = 0;
188
189         do {
190                 c = arg[++j];
191
192                 switch (c) {
193                 case 'o':
194                 case 'O':
195                         opt->sched_type_list[i++] = RTE_SCHED_TYPE_ORDERED;
196                         break;
197                 case 'a':
198                 case 'A':
199                         opt->sched_type_list[i++] = RTE_SCHED_TYPE_ATOMIC;
200                         break;
201                 case 'p':
202                 case 'P':
203                         opt->sched_type_list[i++] = RTE_SCHED_TYPE_PARALLEL;
204                         break;
205                 case ',':
206                         break;
207                 default:
208                         if (c != '\0') {
209                                 evt_err("invalid sched_type %c", c);
210                                 return -EINVAL;
211                         }
212                 }
213         } while (c != '\0');
214
215         opt->nb_stages = i;
216         return 0;
217 }
218
219 static struct option lgopts[] = {
220         { EVT_NB_FLOWS,         1, 0, 0 },
221         { EVT_DEVICE,           1, 0, 0 },
222         { EVT_VERBOSE,          1, 0, 0 },
223         { EVT_TEST,             1, 0, 0 },
224         { EVT_PROD_LCORES,      1, 0, 0 },
225         { EVT_WORK_LCORES,      1, 0, 0 },
226         { EVT_SOCKET_ID,        1, 0, 0 },
227         { EVT_POOL_SZ,          1, 0, 0 },
228         { EVT_NB_PKTS,          1, 0, 0 },
229         { EVT_WKR_DEQ_DEP,      1, 0, 0 },
230         { EVT_SCHED_TYPE_LIST,  1, 0, 0 },
231         { EVT_FWD_LATENCY,      0, 0, 0 },
232         { EVT_QUEUE_PRIORITY,   0, 0, 0 },
233         { EVT_PROD_ETHDEV,      0, 0, 0 },
234         { EVT_HELP,             0, 0, 0 },
235         { NULL,                 0, 0, 0 }
236 };
237
238 static int
239 evt_opts_parse_long(int opt_idx, struct evt_options *opt)
240 {
241         unsigned int i;
242
243         struct long_opt_parser parsermap[] = {
244                 { EVT_NB_FLOWS, evt_parse_nb_flows},
245                 { EVT_DEVICE, evt_parse_dev_id},
246                 { EVT_VERBOSE, evt_parse_verbose},
247                 { EVT_TEST, evt_parse_test_name},
248                 { EVT_PROD_LCORES, evt_parse_plcores},
249                 { EVT_WORK_LCORES, evt_parse_work_lcores},
250                 { EVT_SOCKET_ID, evt_parse_socket_id},
251                 { EVT_POOL_SZ, evt_parse_pool_sz},
252                 { EVT_NB_PKTS, evt_parse_nb_pkts},
253                 { EVT_WKR_DEQ_DEP, evt_parse_wkr_deq_dep},
254                 { EVT_SCHED_TYPE_LIST, evt_parse_sched_type_list},
255                 { EVT_FWD_LATENCY, evt_parse_fwd_latency},
256                 { EVT_QUEUE_PRIORITY, evt_parse_queue_priority},
257                 { EVT_PROD_ETHDEV, evt_parse_eth_prod_type},
258         };
259
260         for (i = 0; i < RTE_DIM(parsermap); i++) {
261                 if (strncmp(lgopts[opt_idx].name, parsermap[i].lgopt_name,
262                                 strlen(parsermap[i].lgopt_name)) == 0)
263                         return parsermap[i].parser_fn(opt, optarg);
264         }
265
266         return -EINVAL;
267 }
268
269 int
270 evt_options_parse(struct evt_options *opt, int argc, char **argv)
271 {
272         int opts, retval, opt_idx;
273
274         while ((opts = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) {
275                 switch (opts) {
276                 case 0: /* long options */
277                         if (!strcmp(lgopts[opt_idx].name, "help")) {
278                                 usage(argv[0]);
279                                 exit(EXIT_SUCCESS);
280                         }
281
282                         retval = evt_opts_parse_long(opt_idx, opt);
283                         if (retval != 0)
284                                 return retval;
285                         break;
286                 default:
287                         return -EINVAL;
288                 }
289         }
290         return 0;
291 }
292
293 void
294 evt_options_dump(struct evt_options *opt)
295 {
296         int lcore_id;
297         struct rte_event_dev_info dev_info;
298
299         rte_event_dev_info_get(opt->dev_id, &dev_info);
300         evt_dump("driver", "%s", dev_info.driver_name);
301         evt_dump("test", "%s", opt->test_name);
302         evt_dump("dev", "%d", opt->dev_id);
303         evt_dump("verbose_level", "%d", opt->verbose_level);
304         evt_dump("socket_id", "%d", opt->socket_id);
305         evt_dump("pool_sz", "%d", opt->pool_sz);
306         evt_dump("master lcore", "%d", rte_get_master_lcore());
307         evt_dump("nb_pkts", "%"PRIu64, opt->nb_pkts);
308         evt_dump_begin("available lcores");
309         RTE_LCORE_FOREACH(lcore_id)
310                 printf("%d ", lcore_id);
311         evt_dump_end;
312         evt_dump_nb_flows(opt);
313         evt_dump_worker_dequeue_depth(opt);
314 }