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