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 /* Add the dump_* tests cases 8< */ 112 static void cmd_dump_parsed(void *parsed_result, 113 __rte_unused struct cmdline *cl, 114 __rte_unused void *data) 115 { 116 struct cmd_dump_result *res = parsed_result; 117 118 if (!strcmp(res->dump, "dump_physmem")) 119 rte_dump_physmem_layout(stdout); 120 else if (!strcmp(res->dump, "dump_memzone")) 121 rte_memzone_dump(stdout); 122 else if (!strcmp(res->dump, "dump_struct_sizes")) 123 dump_struct_sizes(); 124 else if (!strcmp(res->dump, "dump_ring")) 125 rte_ring_list_dump(stdout); 126 else if (!strcmp(res->dump, "dump_mempool")) 127 rte_mempool_list_dump(stdout); 128 else if (!strcmp(res->dump, "dump_devargs")) 129 rte_devargs_dump(stdout); 130 else if (!strcmp(res->dump, "dump_log_types")) 131 rte_log_dump(stdout); 132 else if (!strcmp(res->dump, "dump_malloc_stats")) 133 rte_malloc_dump_stats(stdout, NULL); 134 else if (!strcmp(res->dump, "dump_malloc_heaps")) 135 rte_malloc_dump_heaps(stdout); 136 } 137 138 cmdline_parse_token_string_t cmd_dump_dump = 139 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, 140 "dump_physmem#" 141 "dump_memzone#" 142 "dump_struct_sizes#" 143 "dump_ring#" 144 "dump_mempool#" 145 "dump_malloc_stats#" 146 "dump_malloc_heaps#" 147 "dump_devargs#" 148 "dump_log_types"); 149 150 cmdline_parse_inst_t cmd_dump = { 151 .f = cmd_dump_parsed, /* function to call */ 152 .data = NULL, /* 2nd arg of func */ 153 .help_str = "dump status", 154 .tokens = { /* token list, NULL terminated */ 155 (void *)&cmd_dump_dump, 156 NULL, 157 }, 158 }; 159 /* >8 End of add the dump_* tests cases */ 160 161 /****************/ 162 163 struct cmd_dump_one_result { 164 cmdline_fixed_string_t dump; 165 cmdline_fixed_string_t name; 166 }; 167 168 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, 169 __rte_unused void *data) 170 { 171 struct cmd_dump_one_result *res = parsed_result; 172 173 if (!strcmp(res->dump, "dump_ring")) { 174 struct rte_ring *r; 175 r = rte_ring_lookup(res->name); 176 if (r == NULL) { 177 cmdline_printf(cl, "Cannot find ring\n"); 178 return; 179 } 180 rte_ring_dump(stdout, r); 181 } 182 else if (!strcmp(res->dump, "dump_mempool")) { 183 struct rte_mempool *mp; 184 mp = rte_mempool_lookup(res->name); 185 if (mp == NULL) { 186 cmdline_printf(cl, "Cannot find mempool\n"); 187 return; 188 } 189 rte_mempool_dump(stdout, mp); 190 } 191 } 192 193 cmdline_parse_token_string_t cmd_dump_one_dump = 194 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, 195 "dump_ring#dump_mempool"); 196 197 cmdline_parse_token_string_t cmd_dump_one_name = 198 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); 199 200 cmdline_parse_inst_t cmd_dump_one = { 201 .f = cmd_dump_one_parsed, /* function to call */ 202 .data = NULL, /* 2nd arg of func */ 203 .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>", 204 .tokens = { /* token list, NULL terminated */ 205 (void *)&cmd_dump_one_dump, 206 (void *)&cmd_dump_one_name, 207 NULL, 208 }, 209 }; 210 211 /****************/ 212 213 struct cmd_quit_result { 214 cmdline_fixed_string_t quit; 215 }; 216 217 static void 218 cmd_quit_parsed(__rte_unused void *parsed_result, 219 struct cmdline *cl, 220 __rte_unused void *data) 221 { 222 cmdline_quit(cl); 223 } 224 225 cmdline_parse_token_string_t cmd_quit_quit = 226 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, 227 "quit"); 228 229 cmdline_parse_inst_t cmd_quit = { 230 .f = cmd_quit_parsed, /* function to call */ 231 .data = NULL, /* 2nd arg of func */ 232 .help_str = "exit application", 233 .tokens = { /* token list, NULL terminated */ 234 (void *)&cmd_quit_quit, 235 NULL, 236 }, 237 }; 238 239 /****************/ 240 241 struct cmd_set_rxtx_result { 242 cmdline_fixed_string_t set; 243 cmdline_fixed_string_t mode; 244 }; 245 246 static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl, 247 __rte_unused void *data) 248 { 249 struct cmd_set_rxtx_result *res = parsed_result; 250 if (test_set_rxtx_conf(res->mode) < 0) 251 cmdline_printf(cl, "Cannot find such mode\n"); 252 } 253 254 cmdline_parse_token_string_t cmd_set_rxtx_set = 255 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set, 256 "set_rxtx_mode"); 257 258 cmdline_parse_token_string_t cmd_set_rxtx_mode = 259 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL); 260 261 cmdline_parse_inst_t cmd_set_rxtx = { 262 .f = cmd_set_rxtx_parsed, /* function to call */ 263 .data = NULL, /* 2nd arg of func */ 264 .help_str = "set rxtx routine: " 265 "set_rxtx <mode>", 266 .tokens = { /* token list, NULL terminated */ 267 (void *)&cmd_set_rxtx_set, 268 (void *)&cmd_set_rxtx_mode, 269 NULL, 270 }, 271 }; 272 273 /****************/ 274 275 struct cmd_set_rxtx_anchor { 276 cmdline_fixed_string_t set; 277 cmdline_fixed_string_t type; 278 }; 279 280 static void 281 cmd_set_rxtx_anchor_parsed(void *parsed_result, 282 struct cmdline *cl, 283 __rte_unused void *data) 284 { 285 struct cmd_set_rxtx_anchor *res = parsed_result; 286 if (test_set_rxtx_anchor(res->type) < 0) 287 cmdline_printf(cl, "Cannot find such anchor\n"); 288 } 289 290 cmdline_parse_token_string_t cmd_set_rxtx_anchor_set = 291 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set, 292 "set_rxtx_anchor"); 293 294 cmdline_parse_token_string_t cmd_set_rxtx_anchor_type = 295 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL); 296 297 cmdline_parse_inst_t cmd_set_rxtx_anchor = { 298 .f = cmd_set_rxtx_anchor_parsed, /* function to call */ 299 .data = NULL, /* 2nd arg of func */ 300 .help_str = "set rxtx anchor: " 301 "set_rxtx_anchor <type>", 302 .tokens = { /* token list, NULL terminated */ 303 (void *)&cmd_set_rxtx_anchor_set, 304 (void *)&cmd_set_rxtx_anchor_type, 305 NULL, 306 }, 307 }; 308 309 /****************/ 310 311 /* for stream control */ 312 struct cmd_set_rxtx_sc { 313 cmdline_fixed_string_t set; 314 cmdline_fixed_string_t type; 315 }; 316 317 static void 318 cmd_set_rxtx_sc_parsed(void *parsed_result, 319 struct cmdline *cl, 320 __rte_unused void *data) 321 { 322 struct cmd_set_rxtx_sc *res = parsed_result; 323 if (test_set_rxtx_sc(res->type) < 0) 324 cmdline_printf(cl, "Cannot find such stream control\n"); 325 } 326 327 cmdline_parse_token_string_t cmd_set_rxtx_sc_set = 328 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set, 329 "set_rxtx_sc"); 330 331 cmdline_parse_token_string_t cmd_set_rxtx_sc_type = 332 TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL); 333 334 cmdline_parse_inst_t cmd_set_rxtx_sc = { 335 .f = cmd_set_rxtx_sc_parsed, /* function to call */ 336 .data = NULL, /* 2nd arg of func */ 337 .help_str = "set rxtx stream control: " 338 "set_rxtx_sc <type>", 339 .tokens = { /* token list, NULL terminated */ 340 (void *)&cmd_set_rxtx_sc_set, 341 (void *)&cmd_set_rxtx_sc_type, 342 NULL, 343 }, 344 }; 345 346 /****************/ 347 348 349 cmdline_parse_ctx_t main_ctx[] = { 350 (cmdline_parse_inst_t *)&cmd_autotest, 351 (cmdline_parse_inst_t *)&cmd_dump, 352 (cmdline_parse_inst_t *)&cmd_dump_one, 353 (cmdline_parse_inst_t *)&cmd_quit, 354 (cmdline_parse_inst_t *)&cmd_set_rxtx, 355 (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor, 356 (cmdline_parse_inst_t *)&cmd_set_rxtx_sc, 357 NULL, 358 }; 359 360 int commands_init(void) 361 { 362 struct test_command *t; 363 char *commands; 364 int commands_len = 0; 365 366 TAILQ_FOREACH(t, &commands_list, next) { 367 commands_len += strlen(t->command) + 1; 368 } 369 370 commands = (char *)calloc(commands_len, sizeof(char)); 371 if (!commands) 372 return -1; 373 374 TAILQ_FOREACH(t, &commands_list, next) { 375 strlcat(commands, t->command, commands_len); 376 if (TAILQ_NEXT(t, next) != NULL) 377 strlcat(commands, "#", commands_len); 378 } 379 380 cmd_autotest_autotest.string_data.str = commands; 381 return 0; 382 } 383