1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stdio.h> 35 #include <stdarg.h> 36 #include <stdint.h> 37 #include <string.h> 38 #include <stdlib.h> 39 #include <netinet/in.h> 40 #include <termios.h> 41 #ifndef __linux__ 42 #include <net/socket.h> 43 #endif 44 #include <inttypes.h> 45 #include <errno.h> 46 #include <sys/queue.h> 47 48 #include <rte_common.h> 49 #include <rte_log.h> 50 #include <rte_debug.h> 51 #include <rte_memory.h> 52 #include <rte_memcpy.h> 53 #include <rte_memzone.h> 54 #include <rte_launch.h> 55 #include <rte_cycles.h> 56 #include <rte_tailq.h> 57 #include <rte_eal.h> 58 #include <rte_per_lcore.h> 59 #include <rte_lcore.h> 60 #include <rte_atomic.h> 61 #include <rte_branch_prediction.h> 62 #include <rte_ring.h> 63 #include <rte_mempool.h> 64 #include <rte_mbuf.h> 65 #include <rte_timer.h> 66 67 #include <cmdline_rdline.h> 68 #include <cmdline_parse.h> 69 #include <cmdline_parse_ipaddr.h> 70 #include <cmdline_parse_num.h> 71 #include <cmdline_parse_string.h> 72 #include <cmdline.h> 73 74 #include "test.h" 75 76 /****************/ 77 78 struct cmd_autotest_result { 79 cmdline_fixed_string_t autotest; 80 }; 81 82 static void cmd_autotest_parsed(void *parsed_result, 83 __attribute__((unused)) struct cmdline *cl, 84 __attribute__((unused)) void *data) 85 { 86 struct cmd_autotest_result *res = parsed_result; 87 int ret = 0; 88 int all = 0; 89 90 if (!strcmp(res->autotest, "all_autotests")) 91 all = 1; 92 93 if (all || !strcmp(res->autotest, "version_autotest")) 94 ret |= test_version(); 95 if (all || !strcmp(res->autotest, "eal_fs_autotest")) 96 ret |= test_eal_fs(); 97 if (all || !strcmp(res->autotest, "debug_autotest")) 98 ret |= test_debug(); 99 if (all || !strcmp(res->autotest, "pci_autotest")) 100 ret |= test_pci(); 101 if (all || !strcmp(res->autotest, "prefetch_autotest")) 102 ret |= test_prefetch(); 103 if (all || !strcmp(res->autotest, "byteorder_autotest")) 104 ret |= test_byteorder(); 105 if (all || !strcmp(res->autotest, "per_lcore_autotest")) 106 ret |= test_per_lcore(); 107 if (all || !strcmp(res->autotest, "atomic_autotest")) 108 ret |= test_atomic(); 109 if (all || !strcmp(res->autotest, "malloc_autotest")) 110 ret |= test_malloc(); 111 if (all || !strcmp(res->autotest, "spinlock_autotest")) 112 ret |= test_spinlock(); 113 if (all || !strcmp(res->autotest, "memory_autotest")) 114 ret |= test_memory(); 115 if (all || !strcmp(res->autotest, "memzone_autotest")) 116 ret |= test_memzone(); 117 if (all || !strcmp(res->autotest, "rwlock_autotest")) 118 ret |= test_rwlock(); 119 if (all || !strcmp(res->autotest, "mbuf_autotest")) 120 ret |= test_mbuf(); 121 if (all || !strcmp(res->autotest, "logs_autotest")) 122 ret |= test_logs(); 123 if (all || !strcmp(res->autotest, "errno_autotest")) 124 ret |= test_errno(); 125 if (all || !strcmp(res->autotest, "hash_autotest")) 126 ret |= test_hash(); 127 if (all || !strcmp(res->autotest, "hash_perf_autotest")) 128 ret |= test_hash_perf(); 129 if (all || !strcmp(res->autotest, "lpm_autotest")) 130 ret |= test_lpm(); 131 if (all || !strcmp(res->autotest, "lpm6_autotest")) 132 ret |= test_lpm6(); 133 if (all || !strcmp(res->autotest, "cpuflags_autotest")) 134 ret |= test_cpuflags(); 135 if (all || !strcmp(res->autotest, "cmdline_autotest")) 136 ret |= test_cmdline(); 137 /* tailq autotest must go after all lpm and hashs tests or any other 138 * tests which need to create tailq objects (ring and mempool are implicitly 139 * created in earlier tests so can go later) 140 */ 141 if (all || !strcmp(res->autotest, "tailq_autotest")) 142 ret |= test_tailq(); 143 if (all || !strcmp(res->autotest, "multiprocess_autotest")) 144 ret |= test_mp_secondary(); 145 if (all || !strcmp(res->autotest, "memcpy_autotest")) 146 ret |= test_memcpy(); 147 if (all || !strcmp(res->autotest, "string_autotest")) 148 ret |= test_string_fns(); 149 if (all || !strcmp(res->autotest, "eal_flags_autotest")) 150 ret |= test_eal_flags(); 151 if (all || !strcmp(res->autotest, "alarm_autotest")) 152 ret |= test_alarm(); 153 if (all || !strcmp(res->autotest, "interrupt_autotest")) 154 ret |= test_interrupt(); 155 if (all || !strcmp(res->autotest, "cycles_autotest")) 156 ret |= test_cycles(); 157 if (all || !strcmp(res->autotest, "ring_autotest")) 158 ret |= test_ring(); 159 if (all || !strcmp(res->autotest, "ring_perf_autotest")) 160 ret |= test_ring_perf(); 161 if (all || !strcmp(res->autotest, "timer_autotest")) 162 ret |= test_timer(); 163 if (all || !strcmp(res->autotest, "mempool_autotest")) 164 ret |= test_mempool(); 165 if (all || !strcmp(res->autotest, "mempool_perf_autotest")) 166 ret |= test_mempool_perf(); 167 if (all || !strcmp(res->autotest, "memcpy_perf_autotest")) 168 ret |= test_memcpy_perf(); 169 if (all || !strcmp(res->autotest, "func_reentrancy_autotest")) 170 ret |= test_func_reentrancy(); 171 if (all || !strcmp(res->autotest, "red_autotest")) 172 ret |= test_red(); 173 if (all || !strcmp(res->autotest, "sched_autotest")) 174 ret |= test_sched(); 175 if (all || !strcmp(res->autotest, "meter_autotest")) 176 ret |= test_meter(); 177 if (all || !strcmp(res->autotest, "kni_autotest")) 178 ret |= test_kni(); 179 if (all || !strcmp(res->autotest, "pm_autotest")) 180 ret |= test_pmac_pm(); 181 if (all || !strcmp(res->autotest, "acl_autotest")) 182 ret |= test_pmac_acl(); 183 if (all || !strcmp(res->autotest, "power_autotest")) 184 ret |= test_power(); 185 if (all || !strcmp(res->autotest, "common_autotest")) 186 ret |= test_common(); 187 188 if (ret == 0) 189 printf("Test OK\n"); 190 else 191 printf("Test Failed\n"); 192 fflush(stdout); 193 } 194 195 cmdline_parse_token_string_t cmd_autotest_autotest = 196 TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, 197 "pci_autotest#memory_autotest#" 198 "per_lcore_autotest#spinlock_autotest#" 199 "rwlock_autotest#atomic_autotest#" 200 "byteorder_autotest#prefetch_autotest#" 201 "cycles_autotest#logs_autotest#" 202 "memzone_autotest#ring_autotest#" 203 "mempool_autotest#mbuf_autotest#" 204 "timer_autotest#malloc_autotest#" 205 "memcpy_autotest#hash_autotest#" 206 "lpm_autotest#debug_autotest#" 207 "lpm6_autotest#debug_autotest#" 208 "errno_autotest#tailq_autotest#" 209 "string_autotest#multiprocess_autotest#" 210 "cpuflags_autotest#eal_flags_autotest#" 211 "alarm_autotest#interrupt_autotest#" 212 "version_autotest#eal_fs_autotest#" 213 "cmdline_autotest#func_reentrancy_autotest#" 214 "mempool_perf_autotest#hash_perf_autotest#" 215 "memcpy_perf_autotest#ring_perf_autotest#" 216 "red_autotest#meter_autotest#sched_autotest#" 217 "memcpy_perf_autotest#kni_autotest#" 218 "pm_autotest#acl_autotest#power_autotest#" 219 "common_autotest#all_autotests"); 220 221 cmdline_parse_inst_t cmd_autotest = { 222 .f = cmd_autotest_parsed, /* function to call */ 223 .data = NULL, /* 2nd arg of func */ 224 .help_str = "launch autotest", 225 .tokens = { /* token list, NULL terminated */ 226 (void *)&cmd_autotest_autotest, 227 NULL, 228 }, 229 }; 230 231 /****************/ 232 233 struct cmd_dump_result { 234 cmdline_fixed_string_t dump; 235 }; 236 237 static void 238 dump_struct_sizes(void) 239 { 240 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t)); 241 DUMP_SIZE(struct rte_mbuf); 242 DUMP_SIZE(struct rte_pktmbuf); 243 DUMP_SIZE(struct rte_ctrlmbuf); 244 DUMP_SIZE(struct rte_mempool); 245 DUMP_SIZE(struct rte_ring); 246 #undef DUMP_SIZE 247 } 248 249 static void cmd_dump_parsed(void *parsed_result, 250 __attribute__((unused)) struct cmdline *cl, 251 __attribute__((unused)) void *data) 252 { 253 struct cmd_dump_result *res = parsed_result; 254 255 if (!strcmp(res->dump, "dump_physmem")) 256 rte_dump_physmem_layout(); 257 else if (!strcmp(res->dump, "dump_memzone")) 258 rte_memzone_dump(); 259 else if (!strcmp(res->dump, "dump_log_history")) 260 rte_log_dump_history(); 261 else if (!strcmp(res->dump, "dump_struct_sizes")) 262 dump_struct_sizes(); 263 else if (!strcmp(res->dump, "dump_ring")) 264 rte_ring_list_dump(); 265 else if (!strcmp(res->dump, "dump_mempool")) 266 rte_mempool_list_dump(); 267 } 268 269 cmdline_parse_token_string_t cmd_dump_dump = 270 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, 271 "dump_physmem#dump_memzone#dump_log_history#" 272 "dump_struct_sizes#dump_ring#dump_mempool"); 273 274 cmdline_parse_inst_t cmd_dump = { 275 .f = cmd_dump_parsed, /* function to call */ 276 .data = NULL, /* 2nd arg of func */ 277 .help_str = "dump status", 278 .tokens = { /* token list, NULL terminated */ 279 (void *)&cmd_dump_dump, 280 NULL, 281 }, 282 }; 283 284 /****************/ 285 286 struct cmd_dump_one_result { 287 cmdline_fixed_string_t dump; 288 cmdline_fixed_string_t name; 289 }; 290 291 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, 292 __attribute__((unused)) void *data) 293 { 294 struct cmd_dump_one_result *res = parsed_result; 295 296 if (!strcmp(res->dump, "dump_ring")) { 297 struct rte_ring *r; 298 r = rte_ring_lookup(res->name); 299 if (r == NULL) { 300 cmdline_printf(cl, "Cannot find ring\n"); 301 return; 302 } 303 rte_ring_dump(r); 304 } 305 else if (!strcmp(res->dump, "dump_mempool")) { 306 struct rte_mempool *mp; 307 mp = rte_mempool_lookup(res->name); 308 if (mp == NULL) { 309 cmdline_printf(cl, "Cannot find mempool\n"); 310 return; 311 } 312 rte_mempool_dump(mp); 313 } 314 } 315 316 cmdline_parse_token_string_t cmd_dump_one_dump = 317 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, 318 "dump_ring#dump_mempool"); 319 320 cmdline_parse_token_string_t cmd_dump_one_name = 321 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); 322 323 cmdline_parse_inst_t cmd_dump_one = { 324 .f = cmd_dump_one_parsed, /* function to call */ 325 .data = NULL, /* 2nd arg of func */ 326 .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>", 327 .tokens = { /* token list, NULL terminated */ 328 (void *)&cmd_dump_one_dump, 329 (void *)&cmd_dump_one_name, 330 NULL, 331 }, 332 }; 333 334 /****************/ 335 336 struct cmd_set_ring_result { 337 cmdline_fixed_string_t set; 338 cmdline_fixed_string_t name; 339 uint32_t value; 340 }; 341 342 static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl, 343 __attribute__((unused)) void *data) 344 { 345 struct cmd_set_ring_result *res = parsed_result; 346 struct rte_ring *r; 347 int ret; 348 349 r = rte_ring_lookup(res->name); 350 if (r == NULL) { 351 cmdline_printf(cl, "Cannot find ring\n"); 352 return; 353 } 354 355 if (!strcmp(res->set, "set_watermark")) { 356 ret = rte_ring_set_water_mark(r, res->value); 357 if (ret != 0) 358 cmdline_printf(cl, "Cannot set water mark\n"); 359 } 360 } 361 362 cmdline_parse_token_string_t cmd_set_ring_set = 363 TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set, 364 "set_watermark"); 365 366 cmdline_parse_token_string_t cmd_set_ring_name = 367 TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL); 368 369 cmdline_parse_token_num_t cmd_set_ring_value = 370 TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32); 371 372 cmdline_parse_inst_t cmd_set_ring = { 373 .f = cmd_set_ring_parsed, /* function to call */ 374 .data = NULL, /* 2nd arg of func */ 375 .help_str = "set watermark: " 376 "set_watermark <ring_name> <value>", 377 .tokens = { /* token list, NULL terminated */ 378 (void *)&cmd_set_ring_set, 379 (void *)&cmd_set_ring_name, 380 (void *)&cmd_set_ring_value, 381 NULL, 382 }, 383 }; 384 385 /****************/ 386 387 struct cmd_quit_result { 388 cmdline_fixed_string_t quit; 389 }; 390 391 static void 392 cmd_quit_parsed(__attribute__((unused)) void *parsed_result, 393 struct cmdline *cl, 394 __attribute__((unused)) void *data) 395 { 396 cmdline_quit(cl); 397 } 398 399 cmdline_parse_token_string_t cmd_quit_quit = 400 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, 401 "quit"); 402 403 cmdline_parse_inst_t cmd_quit = { 404 .f = cmd_quit_parsed, /* function to call */ 405 .data = NULL, /* 2nd arg of func */ 406 .help_str = "exit application", 407 .tokens = { /* token list, NULL terminated */ 408 (void *)&cmd_quit_quit, 409 NULL, 410 }, 411 }; 412 413 /****************/ 414 415 cmdline_parse_ctx_t main_ctx[] = { 416 (cmdline_parse_inst_t *)&cmd_autotest, 417 (cmdline_parse_inst_t *)&cmd_dump, 418 (cmdline_parse_inst_t *)&cmd_dump_one, 419 (cmdline_parse_inst_t *)&cmd_set_ring, 420 (cmdline_parse_inst_t *)&cmd_quit, 421 NULL, 422 }; 423 424