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