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