xref: /dpdk/app/test/commands.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5 
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <netinet/in.h>
12 #include <termios.h>
13 #include <inttypes.h>
14 #include <errno.h>
15 #include <sys/queue.h>
16 
17 #include <rte_common.h>
18 #include <rte_log.h>
19 #include <rte_debug.h>
20 #include <rte_memory.h>
21 #include <rte_memcpy.h>
22 #include <rte_memzone.h>
23 #include <rte_launch.h>
24 #include <rte_cycles.h>
25 #include <rte_eal.h>
26 #include <rte_per_lcore.h>
27 #include <rte_lcore.h>
28 #include <rte_atomic.h>
29 #include <rte_branch_prediction.h>
30 #include <rte_ring.h>
31 #include <rte_malloc.h>
32 #include <rte_mempool.h>
33 #include <rte_mbuf.h>
34 #include <rte_devargs.h>
35 
36 #include <cmdline_rdline.h>
37 #include <cmdline_parse.h>
38 #include <cmdline_parse_ipaddr.h>
39 #include <cmdline_parse_num.h>
40 #include <cmdline_parse_string.h>
41 #include <cmdline.h>
42 #include <rte_string_fns.h>
43 
44 #include "test.h"
45 
46 /****************/
47 
48 static struct test_commands_list commands_list =
49 	TAILQ_HEAD_INITIALIZER(commands_list);
50 
51 void
52 add_test_command(struct test_command *t)
53 {
54 	TAILQ_INSERT_TAIL(&commands_list, t, next);
55 }
56 
57 struct cmd_autotest_result {
58 	cmdline_fixed_string_t autotest;
59 };
60 
61 static void cmd_autotest_parsed(void *parsed_result,
62 				__rte_unused struct cmdline *cl,
63 				__rte_unused void *data)
64 {
65 	struct test_command *t;
66 	struct cmd_autotest_result *res = parsed_result;
67 	int ret = 0;
68 
69 	TAILQ_FOREACH(t, &commands_list, next) {
70 		if (!strcmp(res->autotest, t->command))
71 			ret = t->callback();
72 	}
73 
74 	last_test_result = ret;
75 	if (ret == 0)
76 		printf("Test OK\n");
77 	else if (ret == TEST_SKIPPED)
78 		printf("Test Skipped\n");
79 	else
80 		printf("Test Failed\n");
81 	fflush(stdout);
82 }
83 
84 cmdline_parse_token_string_t cmd_autotest_autotest =
85 	TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
86 				 "");
87 
88 cmdline_parse_inst_t cmd_autotest = {
89 	.f = cmd_autotest_parsed,  /* function to call */
90 	.data = NULL,      /* 2nd arg of func */
91 	.help_str = "launch autotest",
92 	.tokens = {        /* token list, NULL terminated */
93 		(void *)&cmd_autotest_autotest,
94 		NULL,
95 	},
96 };
97 
98 /****************/
99 
100 struct cmd_dump_result {
101 	cmdline_fixed_string_t dump;
102 };
103 
104 static void
105 dump_struct_sizes(void)
106 {
107 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
108 	DUMP_SIZE(struct rte_mbuf);
109 	DUMP_SIZE(struct rte_mempool);
110 	DUMP_SIZE(struct rte_ring);
111 #undef DUMP_SIZE
112 }
113 
114 static void cmd_dump_parsed(void *parsed_result,
115 			    __rte_unused struct cmdline *cl,
116 			    __rte_unused void *data)
117 {
118 	struct cmd_dump_result *res = parsed_result;
119 
120 	if (!strcmp(res->dump, "dump_physmem"))
121 		rte_dump_physmem_layout(stdout);
122 	else if (!strcmp(res->dump, "dump_memzone"))
123 		rte_memzone_dump(stdout);
124 	else if (!strcmp(res->dump, "dump_struct_sizes"))
125 		dump_struct_sizes();
126 	else if (!strcmp(res->dump, "dump_ring"))
127 		rte_ring_list_dump(stdout);
128 	else if (!strcmp(res->dump, "dump_mempool"))
129 		rte_mempool_list_dump(stdout);
130 	else if (!strcmp(res->dump, "dump_devargs"))
131 		rte_devargs_dump(stdout);
132 	else if (!strcmp(res->dump, "dump_log_types"))
133 		rte_log_dump(stdout);
134 	else if (!strcmp(res->dump, "dump_malloc_stats"))
135 		rte_malloc_dump_stats(stdout, NULL);
136 	else if (!strcmp(res->dump, "dump_malloc_heaps"))
137 		rte_malloc_dump_heaps(stdout);
138 }
139 
140 cmdline_parse_token_string_t cmd_dump_dump =
141 	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
142 				 "dump_physmem#"
143 				 "dump_memzone#"
144 				 "dump_struct_sizes#"
145 				 "dump_ring#"
146 				 "dump_mempool#"
147 				 "dump_malloc_stats#"
148 				 "dump_malloc_heaps#"
149 				 "dump_devargs#"
150 				 "dump_log_types");
151 
152 cmdline_parse_inst_t cmd_dump = {
153 	.f = cmd_dump_parsed,  /* function to call */
154 	.data = NULL,      /* 2nd arg of func */
155 	.help_str = "dump status",
156 	.tokens = {        /* token list, NULL terminated */
157 		(void *)&cmd_dump_dump,
158 		NULL,
159 	},
160 };
161 
162 /****************/
163 
164 struct cmd_dump_one_result {
165 	cmdline_fixed_string_t dump;
166 	cmdline_fixed_string_t name;
167 };
168 
169 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
170 				__rte_unused void *data)
171 {
172 	struct cmd_dump_one_result *res = parsed_result;
173 
174 	if (!strcmp(res->dump, "dump_ring")) {
175 		struct rte_ring *r;
176 		r = rte_ring_lookup(res->name);
177 		if (r == NULL) {
178 			cmdline_printf(cl, "Cannot find ring\n");
179 			return;
180 		}
181 		rte_ring_dump(stdout, r);
182 	}
183 	else if (!strcmp(res->dump, "dump_mempool")) {
184 		struct rte_mempool *mp;
185 		mp = rte_mempool_lookup(res->name);
186 		if (mp == NULL) {
187 			cmdline_printf(cl, "Cannot find mempool\n");
188 			return;
189 		}
190 		rte_mempool_dump(stdout, mp);
191 	}
192 }
193 
194 cmdline_parse_token_string_t cmd_dump_one_dump =
195 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
196 				 "dump_ring#dump_mempool");
197 
198 cmdline_parse_token_string_t cmd_dump_one_name =
199 	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
200 
201 cmdline_parse_inst_t cmd_dump_one = {
202 	.f = cmd_dump_one_parsed,  /* function to call */
203 	.data = NULL,      /* 2nd arg of func */
204 	.help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
205 	.tokens = {        /* token list, NULL terminated */
206 		(void *)&cmd_dump_one_dump,
207 		(void *)&cmd_dump_one_name,
208 		NULL,
209 	},
210 };
211 
212 /****************/
213 
214 struct cmd_quit_result {
215 	cmdline_fixed_string_t quit;
216 };
217 
218 static void
219 cmd_quit_parsed(__rte_unused void *parsed_result,
220 		struct cmdline *cl,
221 		__rte_unused void *data)
222 {
223 	cmdline_quit(cl);
224 }
225 
226 cmdline_parse_token_string_t cmd_quit_quit =
227 	TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
228 				 "quit");
229 
230 cmdline_parse_inst_t cmd_quit = {
231 	.f = cmd_quit_parsed,  /* function to call */
232 	.data = NULL,      /* 2nd arg of func */
233 	.help_str = "exit application",
234 	.tokens = {        /* token list, NULL terminated */
235 		(void *)&cmd_quit_quit,
236 		NULL,
237 	},
238 };
239 
240 /****************/
241 
242 struct cmd_set_rxtx_result {
243 	cmdline_fixed_string_t set;
244 	cmdline_fixed_string_t mode;
245 };
246 
247 static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
248 				__rte_unused void *data)
249 {
250 	struct cmd_set_rxtx_result *res = parsed_result;
251 	if (test_set_rxtx_conf(res->mode) < 0)
252 		cmdline_printf(cl, "Cannot find such mode\n");
253 }
254 
255 cmdline_parse_token_string_t cmd_set_rxtx_set =
256 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
257 				 "set_rxtx_mode");
258 
259 cmdline_parse_token_string_t cmd_set_rxtx_mode =
260 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
261 
262 cmdline_parse_inst_t cmd_set_rxtx = {
263 	.f = cmd_set_rxtx_parsed,  /* function to call */
264 	.data = NULL,      /* 2nd arg of func */
265 	.help_str = "set rxtx routine: "
266 			"set_rxtx <mode>",
267 	.tokens = {        /* token list, NULL terminated */
268 		(void *)&cmd_set_rxtx_set,
269 		(void *)&cmd_set_rxtx_mode,
270 		NULL,
271 	},
272 };
273 
274 /****************/
275 
276 struct cmd_set_rxtx_anchor {
277 	cmdline_fixed_string_t set;
278 	cmdline_fixed_string_t type;
279 };
280 
281 static void
282 cmd_set_rxtx_anchor_parsed(void *parsed_result,
283 			   struct cmdline *cl,
284 			   __rte_unused void *data)
285 {
286 	struct cmd_set_rxtx_anchor *res = parsed_result;
287 	if (test_set_rxtx_anchor(res->type) < 0)
288 		cmdline_printf(cl, "Cannot find such anchor\n");
289 }
290 
291 cmdline_parse_token_string_t cmd_set_rxtx_anchor_set =
292 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set,
293 				 "set_rxtx_anchor");
294 
295 cmdline_parse_token_string_t cmd_set_rxtx_anchor_type =
296 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL);
297 
298 cmdline_parse_inst_t cmd_set_rxtx_anchor = {
299 	.f = cmd_set_rxtx_anchor_parsed,  /* function to call */
300 	.data = NULL,      /* 2nd arg of func */
301 	.help_str = "set rxtx anchor: "
302 			"set_rxtx_anchor <type>",
303 	.tokens = {        /* token list, NULL terminated */
304 		(void *)&cmd_set_rxtx_anchor_set,
305 		(void *)&cmd_set_rxtx_anchor_type,
306 		NULL,
307 	},
308 };
309 
310 /****************/
311 
312 /* for stream control */
313 struct cmd_set_rxtx_sc {
314 	cmdline_fixed_string_t set;
315 	cmdline_fixed_string_t type;
316 };
317 
318 static void
319 cmd_set_rxtx_sc_parsed(void *parsed_result,
320 			   struct cmdline *cl,
321 			   __rte_unused void *data)
322 {
323 	struct cmd_set_rxtx_sc *res = parsed_result;
324 	if (test_set_rxtx_sc(res->type) < 0)
325 		cmdline_printf(cl, "Cannot find such stream control\n");
326 }
327 
328 cmdline_parse_token_string_t cmd_set_rxtx_sc_set =
329 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set,
330 				 "set_rxtx_sc");
331 
332 cmdline_parse_token_string_t cmd_set_rxtx_sc_type =
333 	TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL);
334 
335 cmdline_parse_inst_t cmd_set_rxtx_sc = {
336 	.f = cmd_set_rxtx_sc_parsed,  /* function to call */
337 	.data = NULL,      /* 2nd arg of func */
338 	.help_str = "set rxtx stream control: "
339 			"set_rxtx_sc <type>",
340 	.tokens = {        /* token list, NULL terminated */
341 		(void *)&cmd_set_rxtx_sc_set,
342 		(void *)&cmd_set_rxtx_sc_type,
343 		NULL,
344 	},
345 };
346 
347 /****************/
348 
349 
350 cmdline_parse_ctx_t main_ctx[] = {
351 	(cmdline_parse_inst_t *)&cmd_autotest,
352 	(cmdline_parse_inst_t *)&cmd_dump,
353 	(cmdline_parse_inst_t *)&cmd_dump_one,
354 	(cmdline_parse_inst_t *)&cmd_quit,
355 	(cmdline_parse_inst_t *)&cmd_set_rxtx,
356 	(cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
357 	(cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
358 	NULL,
359 };
360 
361 int commands_init(void)
362 {
363 	struct test_command *t;
364 	char *commands;
365 	int commands_len = 0;
366 
367 	TAILQ_FOREACH(t, &commands_list, next) {
368 		commands_len += strlen(t->command) + 1;
369 	}
370 
371 	commands = (char *)calloc(commands_len, sizeof(char));
372 	if (!commands)
373 		return -1;
374 
375 	TAILQ_FOREACH(t, &commands_list, next) {
376 		strlcat(commands, t->command, commands_len);
377 		if (TAILQ_NEXT(t, next) != NULL)
378 			strlcat(commands, "#", commands_len);
379 	}
380 
381 	cmd_autotest_autotest.string_data.str = commands;
382 	return 0;
383 }
384 
385 int command_valid(const char *cmd)
386 {
387 	struct test_command *t;
388 
389 	TAILQ_FOREACH(t, &commands_list, next) {
390 		if (strcmp(t->command, cmd) == 0)
391 			return 1;
392 	}
393 	return 0;
394 }
395