1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2012 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 35 #include <stdio.h> 36 #include <stdarg.h> 37 #include <stdint.h> 38 #include <string.h> 39 #include <stdlib.h> 40 #include <netinet/in.h> 41 #include <termios.h> 42 #ifndef __linux__ 43 #include <net/socket.h> 44 #endif 45 #include <inttypes.h> 46 #include <errno.h> 47 #include <sys/queue.h> 48 49 #include <rte_common.h> 50 #include <rte_log.h> 51 #include <rte_debug.h> 52 #include <rte_memory.h> 53 #include <rte_memcpy.h> 54 #include <rte_memzone.h> 55 #include <rte_launch.h> 56 #include <rte_cycles.h> 57 #include <rte_tailq.h> 58 #include <rte_eal.h> 59 #include <rte_per_lcore.h> 60 #include <rte_lcore.h> 61 #include <rte_atomic.h> 62 #include <rte_branch_prediction.h> 63 #include <rte_ring.h> 64 #include <rte_mempool.h> 65 #include <rte_mbuf.h> 66 #include <rte_timer.h> 67 68 #include <cmdline_rdline.h> 69 #include <cmdline_parse.h> 70 #include <cmdline_parse_ipaddr.h> 71 #include <cmdline_parse_num.h> 72 #include <cmdline_parse_string.h> 73 #include <cmdline.h> 74 75 #include "test.h" 76 77 /****************/ 78 79 struct cmd_autotest_result { 80 cmdline_fixed_string_t autotest; 81 }; 82 83 static void cmd_autotest_parsed(void *parsed_result, 84 __attribute__((unused)) struct cmdline *cl, 85 __attribute__((unused)) void *data) 86 { 87 struct cmd_autotest_result *res = parsed_result; 88 int ret = 0; 89 int all = 0; 90 91 if (!strcmp(res->autotest, "all_autotests")) 92 all = 1; 93 94 if (all || !strcmp(res->autotest, "version_autotest")) 95 ret |= test_version(); 96 if (all || !strcmp(res->autotest, "debug_autotest")) 97 ret |= test_debug(); 98 if (all || !strcmp(res->autotest, "pci_autotest")) 99 ret |= test_pci(); 100 if (all || !strcmp(res->autotest, "prefetch_autotest")) 101 ret |= test_prefetch(); 102 if (all || !strcmp(res->autotest, "byteorder_autotest")) 103 ret |= test_byteorder(); 104 if (all || !strcmp(res->autotest, "per_lcore_autotest")) 105 ret |= test_per_lcore(); 106 if (all || !strcmp(res->autotest, "atomic_autotest")) 107 ret |= test_atomic(); 108 if (all || !strcmp(res->autotest, "malloc_autotest")) 109 ret |= test_malloc(); 110 if (all || !strcmp(res->autotest, "spinlock_autotest")) 111 ret |= test_spinlock(); 112 if (all || !strcmp(res->autotest, "memory_autotest")) 113 ret |= test_memory(); 114 if (all || !strcmp(res->autotest, "memzone_autotest")) 115 ret |= test_memzone(); 116 if (all || !strcmp(res->autotest, "rwlock_autotest")) 117 ret |= test_rwlock(); 118 if (all || !strcmp(res->autotest, "mbuf_autotest")) 119 ret |= test_mbuf(); 120 if (all || !strcmp(res->autotest, "logs_autotest")) 121 ret |= test_logs(); 122 if (all || !strcmp(res->autotest, "errno_autotest")) 123 ret |= test_errno(); 124 if (all || !strcmp(res->autotest, "hash_autotest")) 125 ret |= test_hash(); 126 if (all || !strcmp(res->autotest, "lpm_autotest")) 127 ret |= test_lpm(); 128 if (all || !strcmp(res->autotest, "cpuflags_autotest")) 129 ret |= test_cpuflags(); 130 /* tailq autotest must go after all lpm and hashs tests or any other 131 * tests which need to create tailq objects (ring and mempool are implicitly 132 * created in earlier tests so can go later) 133 */ 134 if (all || !strcmp(res->autotest, "tailq_autotest")) 135 ret |= test_tailq(); 136 if (all || !strcmp(res->autotest, "multiprocess_autotest")) 137 ret |= test_mp_secondary(); 138 if (all || !strcmp(res->autotest, "memcpy_autotest")) 139 ret |= test_memcpy(); 140 if (all || !strcmp(res->autotest, "string_autotest")) 141 ret |= test_string_fns(); 142 if (all || !strcmp(res->autotest, "eal_flags_autotest")) 143 ret |= test_eal_flags(); 144 if (all || !strcmp(res->autotest, "alarm_autotest")) 145 ret |= test_alarm(); 146 if (all || !strcmp(res->autotest, "interrupt_autotest")) 147 ret |= test_interrupt(); 148 if (all || !strcmp(res->autotest, "cycles_autotest")) 149 ret |= test_cycles(); 150 if (all || !strcmp(res->autotest, "ring_autotest")) 151 ret |= test_ring(); 152 if (all || !strcmp(res->autotest, "timer_autotest")) 153 ret |= test_timer(); 154 if (all || !strcmp(res->autotest, "mempool_autotest")) 155 ret |= test_mempool(); 156 157 if (ret == 0) 158 printf("Test OK\n"); 159 else 160 printf("Test Failed\n"); 161 fflush(stdout); 162 } 163 164 cmdline_parse_token_string_t cmd_autotest_autotest = 165 TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest, 166 "pci_autotest#memory_autotest#" 167 "per_lcore_autotest#spinlock_autotest#" 168 "rwlock_autotest#atomic_autotest#" 169 "byteorder_autotest#prefetch_autotest#" 170 "cycles_autotest#logs_autotest#" 171 "memzone_autotest#ring_autotest#" 172 "mempool_autotest#mbuf_autotest#" 173 "timer_autotest#malloc_autotest#" 174 "memcpy_autotest#hash_autotest#" 175 "lpm_autotest#debug_autotest#" 176 "errno_autotest#tailq_autotest#" 177 "string_autotest#multiprocess_autotest#" 178 "cpuflags_autotest#eal_flags_autotest#" 179 "alarm_autotest#interrupt_autotest#" 180 "version_autotest#" 181 "all_autotests"); 182 183 cmdline_parse_inst_t cmd_autotest = { 184 .f = cmd_autotest_parsed, /* function to call */ 185 .data = NULL, /* 2nd arg of func */ 186 .help_str = "launch autotest", 187 .tokens = { /* token list, NULL terminated */ 188 (void *)&cmd_autotest_autotest, 189 NULL, 190 }, 191 }; 192 193 /****************/ 194 195 struct cmd_dump_result { 196 cmdline_fixed_string_t dump; 197 }; 198 199 static void 200 dump_struct_sizes(void) 201 { 202 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t)); 203 DUMP_SIZE(struct rte_mbuf); 204 DUMP_SIZE(struct rte_pktmbuf); 205 DUMP_SIZE(struct rte_ctrlmbuf); 206 DUMP_SIZE(struct rte_mempool); 207 DUMP_SIZE(struct rte_ring); 208 #undef DUMP_SIZE 209 } 210 211 static void cmd_dump_parsed(void *parsed_result, 212 __attribute__((unused)) struct cmdline *cl, 213 __attribute__((unused)) void *data) 214 { 215 struct cmd_dump_result *res = parsed_result; 216 217 if (!strcmp(res->dump, "dump_physmem")) 218 rte_dump_physmem_layout(); 219 else if (!strcmp(res->dump, "dump_memzone")) 220 rte_memzone_dump(); 221 else if (!strcmp(res->dump, "dump_log_history")) 222 rte_log_dump_history(); 223 else if (!strcmp(res->dump, "dump_struct_sizes")) 224 dump_struct_sizes(); 225 else if (!strcmp(res->dump, "dump_ring")) 226 rte_ring_list_dump(); 227 else if (!strcmp(res->dump, "dump_mempool")) 228 rte_mempool_list_dump(); 229 } 230 231 cmdline_parse_token_string_t cmd_dump_dump = 232 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, 233 "dump_physmem#dump_memzone#dump_log_history#" 234 "dump_struct_sizes#dump_ring#dump_mempool"); 235 236 cmdline_parse_inst_t cmd_dump = { 237 .f = cmd_dump_parsed, /* function to call */ 238 .data = NULL, /* 2nd arg of func */ 239 .help_str = "dump status", 240 .tokens = { /* token list, NULL terminated */ 241 (void *)&cmd_dump_dump, 242 NULL, 243 }, 244 }; 245 246 /****************/ 247 248 struct cmd_dump_one_result { 249 cmdline_fixed_string_t dump; 250 cmdline_fixed_string_t name; 251 }; 252 253 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl, 254 __attribute__((unused)) void *data) 255 { 256 struct cmd_dump_one_result *res = parsed_result; 257 258 if (!strcmp(res->dump, "dump_ring")) { 259 struct rte_ring *r; 260 r = rte_ring_lookup(res->name); 261 if (r == NULL) { 262 cmdline_printf(cl, "Cannot find ring\n"); 263 return; 264 } 265 rte_ring_dump(r); 266 } 267 else if (!strcmp(res->dump, "dump_mempool")) { 268 struct rte_mempool *mp; 269 mp = rte_mempool_lookup(res->name); 270 if (mp == NULL) { 271 cmdline_printf(cl, "Cannot find mempool\n"); 272 return; 273 } 274 rte_mempool_dump(mp); 275 } 276 } 277 278 cmdline_parse_token_string_t cmd_dump_one_dump = 279 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump, 280 "dump_ring#dump_mempool"); 281 282 cmdline_parse_token_string_t cmd_dump_one_name = 283 TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL); 284 285 cmdline_parse_inst_t cmd_dump_one = { 286 .f = cmd_dump_one_parsed, /* function to call */ 287 .data = NULL, /* 2nd arg of func */ 288 .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>", 289 .tokens = { /* token list, NULL terminated */ 290 (void *)&cmd_dump_one_dump, 291 (void *)&cmd_dump_one_name, 292 NULL, 293 }, 294 }; 295 296 /****************/ 297 298 struct cmd_set_ring_result { 299 cmdline_fixed_string_t set; 300 cmdline_fixed_string_t name; 301 uint32_t value; 302 }; 303 304 static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl, 305 __attribute__((unused)) void *data) 306 { 307 struct cmd_set_ring_result *res = parsed_result; 308 struct rte_ring *r; 309 int ret; 310 311 r = rte_ring_lookup(res->name); 312 if (r == NULL) { 313 cmdline_printf(cl, "Cannot find ring\n"); 314 return; 315 } 316 317 if (!strcmp(res->set, "set_quota")) { 318 ret = rte_ring_set_bulk_count(r, res->value); 319 if (ret != 0) 320 cmdline_printf(cl, "Cannot set quota\n"); 321 } 322 else if (!strcmp(res->set, "set_watermark")) { 323 ret = rte_ring_set_water_mark(r, res->value); 324 if (ret != 0) 325 cmdline_printf(cl, "Cannot set water mark\n"); 326 } 327 } 328 329 cmdline_parse_token_string_t cmd_set_ring_set = 330 TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set, 331 "set_quota#set_watermark"); 332 333 cmdline_parse_token_string_t cmd_set_ring_name = 334 TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL); 335 336 cmdline_parse_token_num_t cmd_set_ring_value = 337 TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32); 338 339 cmdline_parse_inst_t cmd_set_ring = { 340 .f = cmd_set_ring_parsed, /* function to call */ 341 .data = NULL, /* 2nd arg of func */ 342 .help_str = "set quota/watermark: " 343 "set_quota|set_watermark <ring_name> <value>", 344 .tokens = { /* token list, NULL terminated */ 345 (void *)&cmd_set_ring_set, 346 (void *)&cmd_set_ring_name, 347 (void *)&cmd_set_ring_value, 348 NULL, 349 }, 350 }; 351 352 /****************/ 353 354 struct cmd_quit_result { 355 cmdline_fixed_string_t quit; 356 }; 357 358 static void 359 cmd_quit_parsed(__attribute__((unused)) void *parsed_result, 360 struct cmdline *cl, 361 __attribute__((unused)) void *data) 362 { 363 cmdline_quit(cl); 364 } 365 366 cmdline_parse_token_string_t cmd_quit_quit = 367 TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, 368 "quit"); 369 370 cmdline_parse_inst_t cmd_quit = { 371 .f = cmd_quit_parsed, /* function to call */ 372 .data = NULL, /* 2nd arg of func */ 373 .help_str = "exit application", 374 .tokens = { /* token list, NULL terminated */ 375 (void *)&cmd_quit_quit, 376 NULL, 377 }, 378 }; 379 380 /****************/ 381 382 cmdline_parse_ctx_t main_ctx[] = { 383 (cmdline_parse_inst_t *)&cmd_autotest, 384 (cmdline_parse_inst_t *)&cmd_dump, 385 (cmdline_parse_inst_t *)&cmd_dump_one, 386 (cmdline_parse_inst_t *)&cmd_set_ring, 387 (cmdline_parse_inst_t *)&cmd_quit, 388 NULL, 389 }; 390 391