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