1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2017 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <string.h> 7 #include <stdint.h> 8 #include <stdbool.h> 9 #include <errno.h> 10 #include <stdarg.h> 11 #include <inttypes.h> 12 #include <sys/queue.h> 13 #include <stdlib.h> 14 #include <getopt.h> 15 #include <unistd.h> 16 #include <strings.h> 17 18 #include <rte_eal.h> 19 #include <rte_common.h> 20 #include <rte_debug.h> 21 #include <rte_ethdev.h> 22 #include <rte_malloc.h> 23 #include <rte_memory.h> 24 #include <rte_memzone.h> 25 #include <rte_launch.h> 26 #include <rte_tailq.h> 27 #include <rte_per_lcore.h> 28 #include <rte_lcore.h> 29 #include <rte_log.h> 30 #include <rte_branch_prediction.h> 31 #include <rte_string_fns.h> 32 #ifdef RTE_LIB_METRICS 33 #include <rte_metrics.h> 34 #endif 35 #include <rte_cycles.h> 36 #ifdef RTE_LIB_SECURITY 37 #include <rte_security.h> 38 #endif 39 #include <rte_cryptodev.h> 40 #include <rte_tm.h> 41 #include <rte_hexdump.h> 42 #include <rte_version.h> 43 #include <rte_eventdev.h> 44 45 /* Maximum long option length for option parsing. */ 46 #define MAX_LONG_OPT_SZ 64 47 #define MAX_STRING_LEN 256 48 49 #define ETHDEV_FWVERS_LEN 32 50 #define RTE_RETA_CONF_GROUP_NUM 32 51 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) 52 #define EEPROM_DUMP_CHUNKSIZE 1024 53 54 #define STATS_BDR_FMT "========================================" 55 #define STATS_BDR_STR(w, s) printf("%.*s%s%.*s\n", w, \ 56 STATS_BDR_FMT, s, w, STATS_BDR_FMT) 57 58 /* mask of enabled ports */ 59 static unsigned long enabled_port_mask; 60 /* Enable stats. */ 61 static uint32_t enable_stats; 62 /* Enable xstats. */ 63 static uint32_t enable_xstats; 64 /* Enable collectd format */ 65 static uint32_t enable_collectd_format; 66 /* FD to send collectd format messages to STDOUT */ 67 static int stdout_fd; 68 /* Host id process is running on */ 69 static char host_id[MAX_LONG_OPT_SZ]; 70 #ifdef RTE_LIB_METRICS 71 /* Enable metrics. */ 72 static uint32_t enable_metrics; 73 #endif 74 /* Enable stats reset. */ 75 static uint32_t reset_stats; 76 /* Enable xstats reset. */ 77 static uint32_t reset_xstats; 78 /* Enable memory info. */ 79 static uint32_t mem_info; 80 /* Enable displaying xstat name. */ 81 static uint32_t enable_xstats_name; 82 static char *xstats_name; 83 84 /* Enable xstats by ids. */ 85 #define MAX_NB_XSTATS_IDS 1024 86 static uint32_t nb_xstats_ids; 87 static uint64_t xstats_ids[MAX_NB_XSTATS_IDS]; 88 89 /* show border */ 90 static char bdr_str[MAX_STRING_LEN]; 91 92 /* Enable show port. */ 93 static uint32_t enable_shw_port; 94 /* Enable show port private info. */ 95 static uint32_t enable_shw_port_priv; 96 /* Enable show tm. */ 97 static uint32_t enable_shw_tm; 98 /* Enable show crypto. */ 99 static uint32_t enable_shw_crypto; 100 /* Enable show ring. */ 101 static uint32_t enable_shw_ring; 102 static char *ring_name; 103 /* Enable show mempool. */ 104 static uint32_t enable_shw_mempool; 105 static char *mempool_name; 106 /* Enable iter mempool. */ 107 static uint32_t enable_iter_mempool; 108 static char *mempool_iter_name; 109 /* Enable dump regs. */ 110 static uint32_t enable_dump_regs; 111 static char *dump_regs_file_prefix; 112 /* Enable show DPDK version. */ 113 static uint32_t enable_shw_version; 114 /* Enable show ethdev firmware version. */ 115 static uint32_t enable_shw_fw_version; 116 /* Enable show RSS reta. */ 117 static uint32_t enable_shw_rss_reta; 118 /* Enable show module eeprom information. */ 119 static uint32_t enable_shw_module_eeprom; 120 121 /* Enable dump Rx/Tx descriptor. */ 122 static uint32_t enable_shw_rx_desc_dump; 123 static uint32_t enable_shw_tx_desc_dump; 124 125 /* Note: Port_queue_id in xstats APIs is 8 bits, so we have a maximum of 126 * 256 ports and queues for event_Dev 127 */ 128 #define MAX_PORTS_QUEUES 256 129 130 struct eventdev_params { 131 uint16_t ports[MAX_PORTS_QUEUES]; 132 uint16_t queues[MAX_PORTS_QUEUES]; 133 uint16_t num_queues; 134 uint16_t num_ports; 135 uint8_t shw_all_queues:1, 136 shw_all_ports:1, 137 dump_xstats:1, 138 reset_xstats:1, 139 shw_device_xstats:1; 140 }; 141 142 static struct eventdev_params eventdev_var[RTE_EVENT_MAX_DEVS]; 143 144 #define DESC_PARAM_NUM 3 145 146 struct desc_param { 147 uint16_t queue_id; /* A queue identifier on this port. */ 148 uint16_t offset; /* The offset of the descriptor starting from tail. */ 149 uint16_t num; /* The number of the descriptors to dump. */ 150 }; 151 152 static struct desc_param rx_desc_param; 153 static struct desc_param tx_desc_param; 154 155 #define RSS_HASH_KEY_SIZE 64 156 157 /* display usage */ 158 static void 159 proc_info_usage(const char *prgname) 160 { 161 printf("%s [EAL options] -- -p PORTMASK\n" 162 " -m to display DPDK memory zones, segments and TAILQ information\n" 163 " -p PORTMASK: hexadecimal bitmask of ports to retrieve stats for\n" 164 " --stats: to display port statistics, enabled by default\n" 165 " --xstats: to display extended port statistics, disabled by " 166 "default\n" 167 #ifdef RTE_LIB_METRICS 168 " --metrics: to display derived metrics of the ports, disabled by " 169 "default\n" 170 #endif 171 " --xstats-name NAME: to display single xstat id by NAME\n" 172 " --xstats-ids IDLIST: to display xstat values by id. " 173 "The argument is comma-separated list of xstat ids to print out.\n" 174 " --stats-reset: to reset port statistics\n" 175 " --xstats-reset: to reset port extended statistics\n" 176 " --collectd-format: to print statistics to STDOUT in expected by collectd format\n" 177 " --host-id STRING: host id used to identify the system process is running on\n" 178 " --show-port: to display ports information\n" 179 " --show-port-private: to display ports private information\n" 180 " --show-tm: to display traffic manager information for ports\n" 181 " --show-crypto: to display crypto information\n" 182 " --show-ring[=name]: to display ring information\n" 183 " --show-mempool[=name]: to display mempool information\n" 184 " --version: to display DPDK version\n" 185 " --firmware-version: to display ethdev firmware version\n" 186 " --show-rss-reta: to display ports redirection table\n" 187 " --show-module-eeprom: to display ports module eeprom information\n" 188 " --show-rx-descriptor queue_id:offset:num to display ports Rx descriptor information. " 189 "queue_id: A Rx queue identifier on this port. " 190 "offset: The offset of the descriptor starting from tail. " 191 "num: The number of the descriptors to dump.\n" 192 " --show-tx-descriptor queue_id:offset:num to display ports Tx descriptor information. " 193 "queue_id: A Tx queue identifier on this port. " 194 "offset: The offset of the descriptor starting from tail. " 195 "num: The number of the descriptors to dump.\n" 196 " --iter-mempool=name: iterate mempool elements to display content\n" 197 " --dump-regs=file-prefix: dump registers to file with the file-prefix\n" 198 " --show-edev-queue-xstats=queue_num:evdev_id or *:evdev_id to get queue xstats for specified queue or all queues;\n" 199 " --show-edev-port-xstats=port_num:evdev_id or *:evdev_id to get queue xstats for specified port or all ports;\n" 200 " --edev-dump-xstats=evdev_id to dump all event_dev xstats for specified eventdev device;\n" 201 " --edev-reset-xstats=evdev_id to reset event_dev xstats after reading;\n" 202 " --show-edev-device-xstats=evdev_id to get event_dev device xstats for specified eventdev device;\n", 203 prgname); 204 } 205 206 /* 207 * Parse the portmask provided at run time. 208 */ 209 static int 210 parse_portmask(const char *portmask) 211 { 212 char *end = NULL; 213 214 errno = 0; 215 216 /* parse hexadecimal string */ 217 enabled_port_mask = strtoul(portmask, &end, 16); 218 if (portmask[0] == '\0' || end == NULL || *end != '\0' || errno != 0) { 219 fprintf(stderr, "Invalid portmask '%s'\n", portmask); 220 return -1; 221 } 222 223 return 0; 224 } 225 226 /* 227 * Parse ids value list into array 228 */ 229 static int 230 parse_xstats_ids(char *list, uint64_t *ids, int limit) { 231 int length; 232 char *token; 233 char *ctx = NULL; 234 char *endptr; 235 236 length = 0; 237 token = strtok_r(list, ",", &ctx); 238 while (token != NULL) { 239 ids[length] = strtoull(token, &endptr, 10); 240 if (*endptr != '\0') 241 return -EINVAL; 242 243 length++; 244 if (length >= limit) 245 return -E2BIG; 246 247 token = strtok_r(NULL, ",", &ctx); 248 } 249 250 return length; 251 } 252 253 static int 254 parse_descriptor_param(char *list, struct desc_param *desc) 255 { 256 int ret; 257 258 ret = sscanf(list, "%hu:%hu:%hu", &desc->queue_id, &desc->offset, 259 &desc->num); 260 if (ret != DESC_PARAM_NUM) 261 return -EINVAL; 262 263 return 0; 264 } 265 266 static int 267 parse_eventdev_id(const char *str) 268 { 269 unsigned long evdev_id; 270 char *endp; 271 272 evdev_id = strtoul(str, &endp, 0); 273 274 if (*str == '\0' || *endp != '\0' || evdev_id >= rte_event_dev_count()) { 275 fprintf(stderr, "Invalid eventdev id: %s\n", str); 276 return -1; 277 } 278 279 return evdev_id; 280 } 281 282 static int 283 parse_eventdev_dump_xstats_params(const char *list) 284 { 285 int evdev_id = parse_eventdev_id(list); 286 287 if (evdev_id < 0) 288 return -EINVAL; 289 290 eventdev_var[evdev_id].dump_xstats = 1; 291 292 return 0; 293 } 294 295 static int 296 parse_eventdev_reset_xstats_params(const char *list) 297 { 298 int evdev_id = parse_eventdev_id(list); 299 300 if (evdev_id < 0) 301 return -EINVAL; 302 303 eventdev_var[evdev_id].reset_xstats = 1; 304 305 return 0; 306 } 307 308 static int 309 parse_eventdev_device_xstats_params(const char *list) 310 { 311 int evdev_id = parse_eventdev_id(list); 312 313 if (evdev_id < 0) 314 return -EINVAL; 315 316 eventdev_var[evdev_id].shw_device_xstats = 1; 317 318 return 0; 319 } 320 321 static int 322 parse_eventdev_queue_xstats_params(const char *list) 323 { 324 uint16_t queue_id; 325 uint16_t evdev_id; 326 327 if (sscanf(list, "*:%hu", &evdev_id) == 1) { 328 if (evdev_id >= rte_event_dev_count()) { 329 printf("Invalid eventdev id: %hu\n", evdev_id); 330 return -EINVAL; 331 } 332 eventdev_var[evdev_id].shw_all_queues = 1; 333 } else if (sscanf(list, "%hu:%hu", &queue_id, &evdev_id) == 2) { 334 if (evdev_id >= rte_event_dev_count()) { 335 printf("Invalid eventdev id: %hu\n", evdev_id); 336 return -EINVAL; 337 } 338 339 if (queue_id >= MAX_PORTS_QUEUES) { 340 printf("Invalid queue_id: %hu\n", queue_id); 341 return -EINVAL; 342 } 343 344 eventdev_var[evdev_id].queues[eventdev_var[evdev_id].num_queues] = queue_id; 345 eventdev_var[evdev_id].num_queues++; 346 } else { 347 return -EINVAL; 348 } 349 350 return 0; 351 } 352 353 static int 354 parse_eventdev_port_xstats_params(const char *list) 355 { 356 uint16_t port_id; 357 uint16_t evdev_id; 358 359 if (sscanf(list, "*:%hu", &evdev_id) == 1) { 360 if (evdev_id >= rte_event_dev_count()) { 361 printf("Invalid eventdev id: %hu\n", evdev_id); 362 return -EINVAL; 363 } 364 eventdev_var[evdev_id].shw_all_ports = 1; 365 } else if (sscanf(list, "%hu:%hu", &port_id, &evdev_id) == 2) { 366 if (evdev_id >= rte_event_dev_count()) { 367 printf("Invalid eventdev id: %hu\n", evdev_id); 368 return -EINVAL; 369 } 370 371 if (port_id >= MAX_PORTS_QUEUES) { 372 printf("Invalid port_id: %hu\n", port_id); 373 return -EINVAL; 374 } 375 376 eventdev_var[evdev_id].ports[eventdev_var[evdev_id].num_ports] = port_id; 377 eventdev_var[evdev_id].num_ports++; 378 } else { 379 return -EINVAL; 380 } 381 382 return 0; 383 } 384 385 static int 386 proc_info_preparse_args(int argc, char **argv) 387 { 388 char *prgname = argv[0]; 389 int i; 390 391 for (i = 0; i < argc; i++) { 392 /* Print stats or xstats to STDOUT in collectd format */ 393 if (!strncmp(argv[i], "--collectd-format", MAX_LONG_OPT_SZ)) { 394 enable_collectd_format = 1; 395 stdout_fd = dup(STDOUT_FILENO); 396 close(STDOUT_FILENO); 397 } 398 if (!strncmp(argv[i], "--host-id", MAX_LONG_OPT_SZ)) { 399 if ((i + 1) == argc) { 400 printf("Invalid host id or not specified\n"); 401 proc_info_usage(prgname); 402 return -1; 403 } 404 strlcpy(host_id, argv[i + 1], sizeof(host_id)); 405 } 406 } 407 408 if (!strlen(host_id)) { 409 int err = gethostname(host_id, MAX_LONG_OPT_SZ-1); 410 411 if (err) 412 strlcpy(host_id, "unknown", sizeof(host_id)); 413 } 414 415 return 0; 416 } 417 418 /* Parse the argument given in the command line of the application */ 419 static int 420 proc_info_parse_args(int argc, char **argv) 421 { 422 int opt; 423 int option_index; 424 char *prgname = argv[0]; 425 static struct option long_option[] = { 426 {"stats", 0, NULL, 0}, 427 {"stats-reset", 0, NULL, 0}, 428 {"xstats", 0, NULL, 0}, 429 #ifdef RTE_LIB_METRICS 430 {"metrics", 0, NULL, 0}, 431 #endif 432 {"xstats-reset", 0, NULL, 0}, 433 {"xstats-name", required_argument, NULL, 1}, 434 {"collectd-format", 0, NULL, 0}, 435 {"xstats-ids", 1, NULL, 1}, 436 {"host-id", 0, NULL, 0}, 437 {"show-port", 0, NULL, 0}, 438 {"show-port-private", 0, NULL, 0}, 439 {"show-tm", 0, NULL, 0}, 440 {"show-crypto", 0, NULL, 0}, 441 {"show-ring", optional_argument, NULL, 0}, 442 {"show-mempool", optional_argument, NULL, 0}, 443 {"iter-mempool", required_argument, NULL, 0}, 444 {"dump-regs", required_argument, NULL, 0}, 445 {"version", 0, NULL, 0}, 446 {"firmware-version", 0, NULL, 0}, 447 {"show-rss-reta", 0, NULL, 0}, 448 {"show-module-eeprom", 0, NULL, 0}, 449 {"show-rx-descriptor", required_argument, NULL, 1}, 450 {"show-tx-descriptor", required_argument, NULL, 1}, 451 {"show-edev-queue-xstats", required_argument, NULL, 0}, 452 {"show-edev-port-xstats", required_argument, NULL, 0}, 453 {"edev-dump-xstats", required_argument, NULL, 0}, 454 {"edev-reset-xstats", required_argument, NULL, 0}, 455 {"show-edev-device-xstats", required_argument, NULL, 0}, 456 {NULL, 0, 0, 0} 457 }; 458 459 if (argc == 1) 460 proc_info_usage(prgname); 461 462 /* Parse command line */ 463 while ((opt = getopt_long(argc, argv, "p:m", 464 long_option, &option_index)) != EOF) { 465 switch (opt) { 466 /* portmask */ 467 case 'p': 468 if (parse_portmask(optarg) < 0) { 469 proc_info_usage(prgname); 470 return -1; 471 } 472 break; 473 case 'm': 474 mem_info = 1; 475 break; 476 case 0: 477 /* Print stats */ 478 if (!strncmp(long_option[option_index].name, "stats", 479 MAX_LONG_OPT_SZ)) 480 enable_stats = 1; 481 /* Print xstats */ 482 else if (!strncmp(long_option[option_index].name, "xstats", 483 MAX_LONG_OPT_SZ)) 484 enable_xstats = 1; 485 #ifdef RTE_LIB_METRICS 486 else if (!strncmp(long_option[option_index].name, 487 "metrics", 488 MAX_LONG_OPT_SZ)) 489 enable_metrics = 1; 490 #endif 491 /* Reset stats */ 492 if (!strncmp(long_option[option_index].name, "stats-reset", 493 MAX_LONG_OPT_SZ)) 494 reset_stats = 1; 495 /* Reset xstats */ 496 else if (!strncmp(long_option[option_index].name, "xstats-reset", 497 MAX_LONG_OPT_SZ)) 498 reset_xstats = 1; 499 else if (!strncmp(long_option[option_index].name, 500 "show-port", MAX_LONG_OPT_SZ)) 501 enable_shw_port = 1; 502 else if (!strncmp(long_option[option_index].name, 503 "show-port-private", MAX_LONG_OPT_SZ)) 504 enable_shw_port_priv = 1; 505 else if (!strncmp(long_option[option_index].name, 506 "show-tm", MAX_LONG_OPT_SZ)) 507 enable_shw_tm = 1; 508 else if (!strncmp(long_option[option_index].name, 509 "show-crypto", MAX_LONG_OPT_SZ)) 510 enable_shw_crypto = 1; 511 else if (!strncmp(long_option[option_index].name, 512 "show-ring", MAX_LONG_OPT_SZ)) { 513 enable_shw_ring = 1; 514 ring_name = optarg; 515 } else if (!strncmp(long_option[option_index].name, 516 "show-mempool", MAX_LONG_OPT_SZ)) { 517 enable_shw_mempool = 1; 518 mempool_name = optarg; 519 } else if (!strncmp(long_option[option_index].name, 520 "iter-mempool", MAX_LONG_OPT_SZ)) { 521 enable_iter_mempool = 1; 522 mempool_iter_name = optarg; 523 } else if (!strncmp(long_option[option_index].name, 524 "dump-regs", MAX_LONG_OPT_SZ)) { 525 enable_dump_regs = 1; 526 dump_regs_file_prefix = optarg; 527 } else if (!strncmp(long_option[option_index].name, 528 "version", MAX_LONG_OPT_SZ)) 529 enable_shw_version = 1; 530 else if (!strncmp(long_option[option_index].name, 531 "firmware-version", MAX_LONG_OPT_SZ)) 532 enable_shw_fw_version = 1; 533 else if (!strncmp(long_option[option_index].name, 534 "show-rss-reta", MAX_LONG_OPT_SZ)) 535 enable_shw_rss_reta = 1; 536 else if (!strncmp(long_option[option_index].name, 537 "show-module-eeprom", MAX_LONG_OPT_SZ)) 538 enable_shw_module_eeprom = 1; 539 else if (!strncmp(long_option[option_index].name, 540 "edev-dump-xstats", MAX_LONG_OPT_SZ)) { 541 int ret = parse_eventdev_dump_xstats_params(optarg); 542 if (ret < 0) { 543 fprintf(stderr, "Error parsing eventdev dump xstats params: %s\n", 544 strerror(-ret)); 545 return -1; 546 } 547 } else if (!strncmp(long_option[option_index].name, 548 "edev-reset-xstats", MAX_LONG_OPT_SZ)) { 549 int ret = parse_eventdev_reset_xstats_params(optarg); 550 if (ret < 0) { 551 fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n", 552 strerror(-ret)); 553 return -1; 554 } 555 } else if (!strncmp(long_option[option_index].name, 556 "show-edev-device-xstats", MAX_LONG_OPT_SZ)) { 557 int ret = parse_eventdev_device_xstats_params(optarg); 558 if (ret < 0) { 559 fprintf(stderr, "Error parsing eventdev reset xstats params: %s\n", 560 strerror(-ret)); 561 return -1; 562 } 563 } else if (!strncmp(long_option[option_index].name, 564 "show-edev-queue-xstats", MAX_LONG_OPT_SZ)) { 565 int ret = parse_eventdev_queue_xstats_params(optarg); 566 if (ret < 0) { 567 fprintf(stderr, "Error parsing eventdev queue xstats params: %s\n", 568 strerror(-ret)); 569 return -1; 570 } 571 } else if (!strncmp(long_option[option_index].name, 572 "show-edev-port-xstats", MAX_LONG_OPT_SZ)) { 573 int ret = parse_eventdev_port_xstats_params(optarg); 574 if (ret < 0) { 575 fprintf(stderr, "Error parsing eventdev port xstats params: %s\n", 576 strerror(-ret)); 577 return -1; 578 } 579 } 580 break; 581 case 1: 582 /* Print xstat single value given by name*/ 583 if (!strncmp(long_option[option_index].name, 584 "xstats-name", MAX_LONG_OPT_SZ)) { 585 enable_xstats_name = 1; 586 xstats_name = optarg; 587 printf("name:%s:%s\n", 588 long_option[option_index].name, 589 optarg); 590 } else if (!strncmp(long_option[option_index].name, 591 "xstats-ids", 592 MAX_LONG_OPT_SZ)) { 593 int ret = parse_xstats_ids(optarg, 594 xstats_ids, MAX_NB_XSTATS_IDS); 595 if (ret <= 0) { 596 printf("xstats-id list parse error.\n"); 597 return -1; 598 } 599 nb_xstats_ids = ret; 600 } else if (!strncmp(long_option[option_index].name, 601 "show-rx-descriptor", MAX_LONG_OPT_SZ)) { 602 int ret = parse_descriptor_param(optarg, 603 &rx_desc_param); 604 if (ret < 0) { 605 fprintf(stderr, "Error parsing Rx descriptor param: %s\n", 606 strerror(-ret)); 607 return -1; 608 } 609 enable_shw_rx_desc_dump = 1; 610 } else if (!strncmp(long_option[option_index].name, 611 "show-tx-descriptor", MAX_LONG_OPT_SZ)) { 612 int ret = parse_descriptor_param(optarg, 613 &tx_desc_param); 614 if (ret < 0) { 615 fprintf(stderr, "Error parsing Tx descriptor param: %s\n", 616 strerror(-ret)); 617 return -1; 618 } 619 enable_shw_tx_desc_dump = 1; 620 } 621 break; 622 default: 623 proc_info_usage(prgname); 624 return -1; 625 } 626 } 627 return 0; 628 } 629 630 static void 631 meminfo_display(void) 632 { 633 printf("----------- MEMORY_SEGMENTS -----------\n"); 634 rte_dump_physmem_layout(stdout); 635 printf("--------- END_MEMORY_SEGMENTS ---------\n"); 636 637 printf("------------ MEMORY_ZONES -------------\n"); 638 rte_memzone_dump(stdout); 639 printf("---------- END_MEMORY_ZONES -----------\n"); 640 641 printf("---------- MALLOC_HEAP_DUMP -----------\n"); 642 rte_malloc_dump_heaps(stdout); 643 printf("-------- END_MALLOC_HEAP_DUMP ---------\n"); 644 645 printf("------------- TAIL_QUEUES -------------\n"); 646 rte_dump_tailq(stdout); 647 printf("---------- END_TAIL_QUEUES ------------\n"); 648 } 649 650 static void 651 nic_stats_display(uint16_t port_id) 652 { 653 struct rte_eth_stats stats; 654 uint8_t i; 655 656 static const char *nic_stats_border = "########################"; 657 658 rte_eth_stats_get(port_id, &stats); 659 printf("\n %s NIC statistics for port %-2d %s\n", 660 nic_stats_border, port_id, nic_stats_border); 661 662 printf(" RX-packets: %-10"PRIu64" RX-errors: %-10"PRIu64 663 " RX-bytes: %-10"PRIu64"\n", stats.ipackets, stats.ierrors, 664 stats.ibytes); 665 printf(" RX-nombuf: %-10"PRIu64"\n", stats.rx_nombuf); 666 printf(" TX-packets: %-10"PRIu64" TX-errors: %-10"PRIu64 667 " TX-bytes: %-10"PRIu64"\n", stats.opackets, stats.oerrors, 668 stats.obytes); 669 670 printf("\n"); 671 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 672 printf(" Stats reg %2d RX-packets: %-10"PRIu64 673 " RX-errors: %-10"PRIu64 674 " RX-bytes: %-10"PRIu64"\n", 675 i, stats.q_ipackets[i], stats.q_errors[i], stats.q_ibytes[i]); 676 } 677 678 printf("\n"); 679 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 680 printf(" Stats reg %2d TX-packets: %-10"PRIu64 681 " TX-bytes: %-10"PRIu64"\n", 682 i, stats.q_opackets[i], stats.q_obytes[i]); 683 } 684 685 printf(" %s############################%s\n", 686 nic_stats_border, nic_stats_border); 687 } 688 689 static void 690 nic_stats_clear(uint16_t port_id) 691 { 692 printf("\n Clearing NIC stats for port %d\n", port_id); 693 rte_eth_stats_reset(port_id); 694 printf("\n NIC statistics for port %d cleared\n", port_id); 695 } 696 697 static void collectd_resolve_cnt_type(char *cnt_type, size_t cnt_type_len, 698 const char *cnt_name) { 699 char *type_end = strrchr(cnt_name, '_'); 700 701 if ((type_end != NULL) && 702 (strncmp(cnt_name, "rx_", strlen("rx_")) == 0)) { 703 if (strncmp(type_end, "_errors", strlen("_errors")) == 0) 704 strlcpy(cnt_type, "if_rx_errors", cnt_type_len); 705 else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0) 706 strlcpy(cnt_type, "if_rx_dropped", cnt_type_len); 707 else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0) 708 strlcpy(cnt_type, "if_rx_octets", cnt_type_len); 709 else if (strncmp(type_end, "_packets", strlen("_packets")) == 0) 710 strlcpy(cnt_type, "if_rx_packets", cnt_type_len); 711 else if (strncmp(type_end, "_placement", 712 strlen("_placement")) == 0) 713 strlcpy(cnt_type, "if_rx_errors", cnt_type_len); 714 else if (strncmp(type_end, "_buff", strlen("_buff")) == 0) 715 strlcpy(cnt_type, "if_rx_errors", cnt_type_len); 716 else 717 /* Does not fit obvious type: use a more generic one */ 718 strlcpy(cnt_type, "derive", cnt_type_len); 719 } else if ((type_end != NULL) && 720 (strncmp(cnt_name, "tx_", strlen("tx_"))) == 0) { 721 if (strncmp(type_end, "_errors", strlen("_errors")) == 0) 722 strlcpy(cnt_type, "if_tx_errors", cnt_type_len); 723 else if (strncmp(type_end, "_dropped", strlen("_dropped")) == 0) 724 strlcpy(cnt_type, "if_tx_dropped", cnt_type_len); 725 else if (strncmp(type_end, "_bytes", strlen("_bytes")) == 0) 726 strlcpy(cnt_type, "if_tx_octets", cnt_type_len); 727 else if (strncmp(type_end, "_packets", strlen("_packets")) == 0) 728 strlcpy(cnt_type, "if_tx_packets", cnt_type_len); 729 else 730 /* Does not fit obvious type: use a more generic one */ 731 strlcpy(cnt_type, "derive", cnt_type_len); 732 } else if ((type_end != NULL) && 733 (strncmp(cnt_name, "flow_", strlen("flow_"))) == 0) { 734 if (strncmp(type_end, "_filters", strlen("_filters")) == 0) 735 strlcpy(cnt_type, "filter_result", cnt_type_len); 736 else if (strncmp(type_end, "_errors", strlen("_errors")) == 0) 737 strlcpy(cnt_type, "errors", cnt_type_len); 738 } else if ((type_end != NULL) && 739 (strncmp(cnt_name, "mac_", strlen("mac_"))) == 0) { 740 if (strncmp(type_end, "_errors", strlen("_errors")) == 0) 741 strlcpy(cnt_type, "errors", cnt_type_len); 742 } else { 743 /* Does not fit obvious type, or strrchr error: */ 744 /* use a more generic type */ 745 strlcpy(cnt_type, "derive", cnt_type_len); 746 } 747 } 748 749 static void 750 nic_xstats_by_name_display(uint16_t port_id, char *name) 751 { 752 uint64_t id; 753 754 printf("###### NIC statistics for port %-2d, statistic name '%s':\n", 755 port_id, name); 756 757 if (rte_eth_xstats_get_id_by_name(port_id, name, &id) == 0) 758 printf("%s: %"PRIu64"\n", name, id); 759 else 760 printf("Statistic not found...\n"); 761 762 } 763 764 static void 765 nic_xstats_by_ids_display(uint16_t port_id, uint64_t *ids, int len) 766 { 767 struct rte_eth_xstat_name *xstats_names; 768 uint64_t *values; 769 int ret, i; 770 static const char *nic_stats_border = "########################"; 771 772 values = malloc(sizeof(*values) * len); 773 if (values == NULL) { 774 printf("Cannot allocate memory for xstats\n"); 775 return; 776 } 777 778 xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len); 779 if (xstats_names == NULL) { 780 printf("Cannot allocate memory for xstat names\n"); 781 free(values); 782 return; 783 } 784 785 if (len != rte_eth_xstats_get_names_by_id( 786 port_id, xstats_names, len, ids)) { 787 printf("Cannot get xstat names\n"); 788 goto err; 789 } 790 791 printf("###### NIC extended statistics for port %-2d #########\n", 792 port_id); 793 printf("%s############################\n", nic_stats_border); 794 ret = rte_eth_xstats_get_by_id(port_id, ids, values, len); 795 if (ret < 0 || ret > len) { 796 printf("Cannot get xstats\n"); 797 goto err; 798 } 799 800 for (i = 0; i < len; i++) 801 printf("%s: %"PRIu64"\n", 802 xstats_names[i].name, 803 values[i]); 804 805 printf("%s############################\n", nic_stats_border); 806 err: 807 free(values); 808 free(xstats_names); 809 } 810 811 static void 812 nic_xstats_display(uint16_t port_id) 813 { 814 struct rte_eth_xstat_name *xstats_names; 815 uint64_t *values; 816 int len, ret, i; 817 static const char *nic_stats_border = "########################"; 818 819 len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL); 820 if (len < 0) { 821 printf("Cannot get xstats count\n"); 822 return; 823 } 824 values = malloc(sizeof(*values) * len); 825 if (values == NULL) { 826 printf("Cannot allocate memory for xstats\n"); 827 return; 828 } 829 830 xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len); 831 if (xstats_names == NULL) { 832 printf("Cannot allocate memory for xstat names\n"); 833 free(values); 834 return; 835 } 836 if (len != rte_eth_xstats_get_names_by_id( 837 port_id, xstats_names, len, NULL)) { 838 printf("Cannot get xstat names\n"); 839 goto err; 840 } 841 842 printf("###### NIC extended statistics for port %-2d #########\n", 843 port_id); 844 printf("%s############################\n", 845 nic_stats_border); 846 ret = rte_eth_xstats_get_by_id(port_id, NULL, values, len); 847 if (ret < 0 || ret > len) { 848 printf("Cannot get xstats\n"); 849 goto err; 850 } 851 852 for (i = 0; i < len; i++) { 853 if (enable_collectd_format) { 854 char counter_type[MAX_STRING_LEN]; 855 char buf[MAX_STRING_LEN]; 856 size_t n; 857 858 collectd_resolve_cnt_type(counter_type, 859 sizeof(counter_type), 860 xstats_names[i].name); 861 n = snprintf(buf, MAX_STRING_LEN, 862 "PUTVAL %s/dpdkstat-port.%u/%s-%s N:%" 863 PRIu64"\n", host_id, port_id, counter_type, 864 xstats_names[i].name, values[i]); 865 if (n > sizeof(buf) - 1) 866 n = sizeof(buf) - 1; 867 ret = write(stdout_fd, buf, n); 868 if (ret < 0) 869 goto err; 870 } else { 871 printf("%s: %"PRIu64"\n", xstats_names[i].name, 872 values[i]); 873 } 874 } 875 876 printf("%s############################\n", 877 nic_stats_border); 878 err: 879 free(values); 880 free(xstats_names); 881 } 882 883 static void 884 nic_xstats_clear(uint16_t port_id) 885 { 886 int ret; 887 888 printf("\n Clearing NIC xstats for port %d\n", port_id); 889 ret = rte_eth_xstats_reset(port_id); 890 if (ret != 0) { 891 printf("\n Error clearing xstats for port %d: %s\n", port_id, 892 strerror(-ret)); 893 return; 894 } 895 896 printf("\n NIC extended statistics for port %d cleared\n", port_id); 897 } 898 899 #ifdef RTE_LIB_METRICS 900 static void 901 metrics_display(int port_id) 902 { 903 struct rte_metric_value *metrics; 904 struct rte_metric_name *names; 905 int len, ret; 906 static const char *nic_stats_border = "########################"; 907 908 len = rte_metrics_get_names(NULL, 0); 909 if (len < 0) { 910 printf("Cannot get metrics count\n"); 911 return; 912 } 913 if (len == 0) { 914 printf("No metrics to display (none have been registered)\n"); 915 return; 916 } 917 918 metrics = malloc(sizeof(struct rte_metric_value) * len); 919 if (metrics == NULL) { 920 printf("Cannot allocate memory for metrics\n"); 921 return; 922 } 923 924 names = malloc(sizeof(struct rte_metric_name) * len); 925 if (names == NULL) { 926 printf("Cannot allocate memory for metrics names\n"); 927 free(metrics); 928 return; 929 } 930 931 if (len != rte_metrics_get_names(names, len)) { 932 printf("Cannot get metrics names\n"); 933 free(metrics); 934 free(names); 935 return; 936 } 937 938 if (port_id == RTE_METRICS_GLOBAL) 939 printf("###### Non port specific metrics #########\n"); 940 else 941 printf("###### metrics for port %-2d #########\n", port_id); 942 printf("%s############################\n", nic_stats_border); 943 ret = rte_metrics_get_values(port_id, metrics, len); 944 if (ret < 0 || ret > len) { 945 printf("Cannot get metrics values\n"); 946 free(metrics); 947 free(names); 948 return; 949 } 950 951 int i; 952 for (i = 0; i < len; i++) 953 printf("%s: %"PRIu64"\n", names[i].name, metrics[i].value); 954 955 printf("%s############################\n", nic_stats_border); 956 free(metrics); 957 free(names); 958 } 959 #endif 960 961 static void 962 show_security_context(uint16_t portid, bool inline_offload) 963 { 964 void *p_ctx; 965 const struct rte_security_capability *s_cap; 966 967 if (inline_offload) 968 p_ctx = rte_eth_dev_get_sec_ctx(portid); 969 else 970 p_ctx = rte_cryptodev_get_sec_ctx(portid); 971 972 if (p_ctx == NULL) 973 return; 974 975 printf(" - crypto context\n"); 976 printf("\t -- security context - %p\n", p_ctx); 977 printf("\t -- size %u\n", 978 rte_security_session_get_size(p_ctx)); 979 980 s_cap = rte_security_capabilities_get(p_ctx); 981 if (s_cap) { 982 printf("\t -- action (0x%x), protocol (0x%x)," 983 " offload flags (0x%x)\n", 984 s_cap->action, 985 s_cap->protocol, 986 s_cap->ol_flags); 987 printf("\t -- capabilities - oper type %x\n", 988 s_cap->crypto_capabilities->op); 989 } 990 } 991 992 static void 993 show_offloads(uint64_t offloads, 994 const char *(show_offload)(uint64_t)) 995 { 996 printf(" offloads :"); 997 while (offloads != 0) { 998 uint64_t offload_flag = 1ULL << rte_ctz64(offloads); 999 printf(" %s", show_offload(offload_flag)); 1000 offloads &= ~offload_flag; 1001 } 1002 } 1003 1004 static void 1005 show_port(void) 1006 { 1007 int i, ret, j, k; 1008 1009 snprintf(bdr_str, MAX_STRING_LEN, " show - Port PMD "); 1010 STATS_BDR_STR(10, bdr_str); 1011 1012 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 1013 uint16_t mtu = 0; 1014 struct rte_eth_link link; 1015 struct rte_eth_dev_info dev_info; 1016 struct rte_eth_rss_conf rss_conf; 1017 char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; 1018 struct rte_eth_fc_conf fc_conf; 1019 struct rte_ether_addr mac; 1020 struct rte_eth_dev_owner owner; 1021 uint8_t rss_key[RSS_HASH_KEY_SIZE]; 1022 1023 /* Skip if port is not in mask */ 1024 if ((enabled_port_mask & (1ul << i)) == 0) 1025 continue; 1026 1027 /* Skip if port is unused */ 1028 if (!rte_eth_dev_is_valid_port(i)) 1029 continue; 1030 1031 memset(&rss_conf, 0, sizeof(rss_conf)); 1032 1033 snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i); 1034 STATS_BDR_STR(5, bdr_str); 1035 printf(" - generic config\n"); 1036 1037 ret = rte_eth_dev_info_get(i, &dev_info); 1038 if (ret != 0) { 1039 printf("Error during getting device info: %s\n", 1040 strerror(-ret)); 1041 return; 1042 } 1043 1044 printf("\t -- driver %s device %s socket %d\n", 1045 dev_info.driver_name, rte_dev_name(dev_info.device), 1046 rte_eth_dev_socket_id(i)); 1047 1048 ret = rte_eth_dev_owner_get(i, &owner); 1049 if (ret == 0 && owner.id != RTE_ETH_DEV_NO_OWNER) 1050 printf("\t -- owner %#"PRIx64":%s\n", 1051 owner.id, owner.name); 1052 1053 ret = rte_eth_link_get(i, &link); 1054 if (ret < 0) { 1055 printf("Link get failed (port %u): %s\n", 1056 i, rte_strerror(-ret)); 1057 } else { 1058 rte_eth_link_to_str(link_status_text, 1059 sizeof(link_status_text), 1060 &link); 1061 printf("\t%s\n", link_status_text); 1062 } 1063 1064 ret = rte_eth_dev_flow_ctrl_get(i, &fc_conf); 1065 if (ret == 0 && fc_conf.mode != RTE_ETH_FC_NONE) { 1066 printf("\t -- flow control mode %s%s high %u low %u pause %u%s%s\n", 1067 fc_conf.mode == RTE_ETH_FC_RX_PAUSE ? "rx " : 1068 fc_conf.mode == RTE_ETH_FC_TX_PAUSE ? "tx " : 1069 fc_conf.mode == RTE_ETH_FC_FULL ? "full" : "???", 1070 fc_conf.autoneg ? " auto" : "", 1071 fc_conf.high_water, 1072 fc_conf.low_water, 1073 fc_conf.pause_time, 1074 fc_conf.send_xon ? " xon" : "", 1075 fc_conf.mac_ctrl_frame_fwd ? " mac_ctrl" : ""); 1076 } 1077 1078 ret = rte_eth_macaddr_get(i, &mac); 1079 if (ret == 0) { 1080 char ebuf[RTE_ETHER_ADDR_FMT_SIZE]; 1081 1082 rte_ether_format_addr(ebuf, sizeof(ebuf), &mac); 1083 printf("\t -- mac %s\n", ebuf); 1084 } 1085 1086 ret = rte_eth_promiscuous_get(i); 1087 if (ret >= 0) 1088 printf("\t -- promiscuous mode %s\n", 1089 ret > 0 ? "enabled" : "disabled"); 1090 1091 ret = rte_eth_allmulticast_get(i); 1092 if (ret >= 0) 1093 printf("\t -- all multicast mode %s\n", 1094 ret > 0 ? "enabled" : "disabled"); 1095 1096 ret = rte_eth_dev_get_mtu(i, &mtu); 1097 if (ret == 0) 1098 printf("\t -- mtu (%d)\n", mtu); 1099 1100 for (j = 0; j < dev_info.nb_rx_queues; j++) { 1101 struct rte_eth_rxq_info queue_info; 1102 struct rte_eth_burst_mode mode; 1103 int count; 1104 1105 ret = rte_eth_rx_queue_info_get(i, j, &queue_info); 1106 if (ret != 0) 1107 break; 1108 1109 if (j == 0) 1110 printf(" - rx queue\n"); 1111 1112 printf("\t -- %d descriptors ", j); 1113 count = rte_eth_rx_queue_count(i, j); 1114 if (count >= 0) 1115 printf("%d/", count); 1116 printf("%u", queue_info.nb_desc); 1117 1118 if (queue_info.scattered_rx) 1119 printf(" scattered"); 1120 1121 if (queue_info.conf.rx_drop_en) 1122 printf(" drop_en"); 1123 1124 if (queue_info.conf.rx_deferred_start) 1125 printf(" deferred_start"); 1126 1127 if (queue_info.rx_buf_size != 0) 1128 printf(" rx buffer size %u", 1129 queue_info.rx_buf_size); 1130 1131 printf(" mempool %s socket %d", 1132 queue_info.mp->name, 1133 queue_info.mp->socket_id); 1134 1135 if (queue_info.conf.offloads != 0) 1136 show_offloads(queue_info.conf.offloads, rte_eth_dev_rx_offload_name); 1137 1138 if (rte_eth_rx_burst_mode_get(i, j, &mode) == 0) 1139 printf(" burst mode : %s%s", 1140 mode.info, 1141 mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ? 1142 " (per queue)" : ""); 1143 1144 printf("\n"); 1145 } 1146 1147 for (j = 0; j < dev_info.nb_tx_queues; j++) { 1148 struct rte_eth_txq_info queue_info; 1149 struct rte_eth_burst_mode mode; 1150 1151 ret = rte_eth_tx_queue_info_get(i, j, &queue_info); 1152 if (ret != 0) 1153 break; 1154 1155 if (j == 0) 1156 printf(" - tx queue\n"); 1157 1158 printf("\t -- %d descriptors %d", 1159 j, queue_info.nb_desc); 1160 1161 printf(" thresh %u/%u", 1162 queue_info.conf.tx_rs_thresh, 1163 queue_info.conf.tx_free_thresh); 1164 1165 if (queue_info.conf.tx_deferred_start) 1166 printf(" deferred_start"); 1167 1168 if (queue_info.conf.offloads != 0) 1169 show_offloads(queue_info.conf.offloads, rte_eth_dev_tx_offload_name); 1170 1171 if (rte_eth_tx_burst_mode_get(i, j, &mode) == 0) 1172 printf(" burst mode : %s%s", 1173 mode.info, 1174 mode.flags & RTE_ETH_BURST_FLAG_PER_QUEUE ? 1175 " (per queue)" : ""); 1176 1177 printf("\n"); 1178 } 1179 1180 rss_conf.rss_key = rss_key; 1181 rss_conf.rss_key_len = dev_info.hash_key_size; 1182 ret = rte_eth_dev_rss_hash_conf_get(i, &rss_conf); 1183 if (ret == 0) { 1184 printf(" - RSS info\n"); 1185 printf("\t -- key len : %u\n", 1186 rss_conf.rss_key_len); 1187 printf("\t -- key (hex) : "); 1188 for (k = 0; k < rss_conf.rss_key_len; k++) 1189 printf("%02x", rss_conf.rss_key[k]); 1190 printf("\n\t -- hash function : 0x%"PRIx64"\n", 1191 rss_conf.rss_hf); 1192 printf("\t -- hash algorithm : %s\n", 1193 rte_eth_dev_rss_algo_name(rss_conf.algorithm)); 1194 } 1195 1196 #ifdef RTE_LIB_SECURITY 1197 show_security_context(i, true); 1198 #endif 1199 } 1200 } 1201 1202 static void 1203 show_port_private_info(void) 1204 { 1205 int i; 1206 1207 snprintf(bdr_str, MAX_STRING_LEN, " Dump - Ports private information"); 1208 STATS_BDR_STR(10, bdr_str); 1209 1210 RTE_ETH_FOREACH_DEV(i) { 1211 /* Skip if port is not in mask */ 1212 if ((enabled_port_mask & (1ul << i)) == 0) 1213 continue; 1214 1215 snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i); 1216 STATS_BDR_STR(5, bdr_str); 1217 rte_eth_dev_priv_dump(i, stdout); 1218 } 1219 } 1220 1221 static void 1222 display_nodecap_info(int is_leaf, struct rte_tm_node_capabilities *cap) 1223 { 1224 if (cap == NULL) 1225 return; 1226 1227 if (!is_leaf) { 1228 printf("\t -- nonleaf sched max:\n" 1229 "\t\t + children (%u)\n" 1230 "\t\t + sp priorities (%u)\n" 1231 "\t\t + wfq children per group (%u)\n" 1232 "\t\t + wfq groups (%u)\n" 1233 "\t\t + wfq weight (%u)\n", 1234 cap->nonleaf.sched_n_children_max, 1235 cap->nonleaf.sched_sp_n_priorities_max, 1236 cap->nonleaf.sched_wfq_n_children_per_group_max, 1237 cap->nonleaf.sched_wfq_n_groups_max, 1238 cap->nonleaf.sched_wfq_weight_max); 1239 } else { 1240 printf("\t -- leaf cman support:\n" 1241 "\t\t + wred pkt mode (%d)\n" 1242 "\t\t + wred byte mode (%d)\n" 1243 "\t\t + head drop (%d)\n" 1244 "\t\t + wred context private (%d)\n" 1245 "\t\t + wred context shared (%u)\n", 1246 cap->leaf.cman_wred_packet_mode_supported, 1247 cap->leaf.cman_wred_byte_mode_supported, 1248 cap->leaf.cman_head_drop_supported, 1249 cap->leaf.cman_wred_context_private_supported, 1250 cap->leaf.cman_wred_context_shared_n_max); 1251 } 1252 } 1253 1254 static void 1255 display_levelcap_info(int is_leaf, struct rte_tm_level_capabilities *cap) 1256 { 1257 if (cap == NULL) 1258 return; 1259 1260 if (!is_leaf) { 1261 printf("\t -- shaper private: (%d) dual rate (%d)\n", 1262 cap->nonleaf.shaper_private_supported, 1263 cap->nonleaf.shaper_private_dual_rate_supported); 1264 printf("\t -- shaper share: (%u)\n", 1265 cap->nonleaf.shaper_shared_n_max); 1266 printf("\t -- non leaf sched MAX:\n" 1267 "\t\t + children (%u)\n" 1268 "\t\t + sp (%u)\n" 1269 "\t\t + wfq children per group (%u)\n" 1270 "\t\t + wfq groups (%u)\n" 1271 "\t\t + wfq weight (%u)\n", 1272 cap->nonleaf.sched_n_children_max, 1273 cap->nonleaf.sched_sp_n_priorities_max, 1274 cap->nonleaf.sched_wfq_n_children_per_group_max, 1275 cap->nonleaf.sched_wfq_n_groups_max, 1276 cap->nonleaf.sched_wfq_weight_max); 1277 } else { 1278 printf("\t -- shaper private: (%d) dual rate (%d)\n", 1279 cap->leaf.shaper_private_supported, 1280 cap->leaf.shaper_private_dual_rate_supported); 1281 printf("\t -- shaper share: (%u)\n", 1282 cap->leaf.shaper_shared_n_max); 1283 printf(" -- leaf cman support:\n" 1284 "\t\t + wred pkt mode (%d)\n" 1285 "\t\t + wred byte mode (%d)\n" 1286 "\t\t + head drop (%d)\n" 1287 "\t\t + wred context private (%d)\n" 1288 "\t\t + wred context shared (%u)\n", 1289 cap->leaf.cman_wred_packet_mode_supported, 1290 cap->leaf.cman_wred_byte_mode_supported, 1291 cap->leaf.cman_head_drop_supported, 1292 cap->leaf.cman_wred_context_private_supported, 1293 cap->leaf.cman_wred_context_shared_n_max); 1294 } 1295 } 1296 1297 static void 1298 show_tm(void) 1299 { 1300 int ret = 0, check_for_leaf = 0, is_leaf = 0; 1301 unsigned int j, k; 1302 uint16_t i = 0; 1303 1304 snprintf(bdr_str, MAX_STRING_LEN, " show - TM PMD "); 1305 STATS_BDR_STR(10, bdr_str); 1306 1307 RTE_ETH_FOREACH_DEV(i) { 1308 struct rte_eth_dev_info dev_info; 1309 struct rte_tm_capabilities cap; 1310 struct rte_tm_error error; 1311 struct rte_tm_node_capabilities capnode; 1312 struct rte_tm_level_capabilities caplevel; 1313 uint32_t n_leaf_nodes = 0; 1314 1315 memset(&cap, 0, sizeof(cap)); 1316 memset(&error, 0, sizeof(error)); 1317 1318 ret = rte_eth_dev_info_get(i, &dev_info); 1319 if (ret != 0) { 1320 printf("Error during getting device (port %u) info: %s\n", 1321 i, strerror(-ret)); 1322 return; 1323 } 1324 1325 printf(" - Generic for port (%u)\n" 1326 "\t -- driver name %s\n" 1327 "\t -- max vf (%u)\n" 1328 "\t -- max tx queues (%u)\n" 1329 "\t -- number of tx queues (%u)\n", 1330 i, 1331 dev_info.driver_name, 1332 dev_info.max_vfs, 1333 dev_info.max_tx_queues, 1334 dev_info.nb_tx_queues); 1335 1336 ret = rte_tm_capabilities_get(i, &cap, &error); 1337 if (ret) 1338 continue; 1339 1340 printf(" - MAX: nodes (%u) levels (%u) children (%u)\n", 1341 cap.n_nodes_max, 1342 cap.n_levels_max, 1343 cap.sched_n_children_max); 1344 1345 printf(" - identical nodes: non leaf (%d) leaf (%d)\n", 1346 cap.non_leaf_nodes_identical, 1347 cap.leaf_nodes_identical); 1348 1349 printf(" - Shaper MAX:\n" 1350 "\t -- total (%u)\n" 1351 "\t -- private (%u) private dual (%d)\n" 1352 "\t -- shared (%u) shared dual (%u)\n", 1353 cap.shaper_n_max, 1354 cap.shaper_private_n_max, 1355 cap.shaper_private_dual_rate_n_max, 1356 cap.shaper_shared_n_max, 1357 cap.shaper_shared_dual_rate_n_max); 1358 1359 printf(" - mark support:\n"); 1360 printf("\t -- vlan dei: GREEN (%d) YELLOW (%d) RED (%d)\n", 1361 cap.mark_vlan_dei_supported[RTE_COLOR_GREEN], 1362 cap.mark_vlan_dei_supported[RTE_COLOR_YELLOW], 1363 cap.mark_vlan_dei_supported[RTE_COLOR_RED]); 1364 printf("\t -- ip ecn tcp: GREEN (%d) YELLOW (%d) RED (%d)\n", 1365 cap.mark_ip_ecn_tcp_supported[RTE_COLOR_GREEN], 1366 cap.mark_ip_ecn_tcp_supported[RTE_COLOR_YELLOW], 1367 cap.mark_ip_ecn_tcp_supported[RTE_COLOR_RED]); 1368 printf("\t -- ip ecn sctp: GREEN (%d) YELLOW (%d) RED (%d)\n", 1369 cap.mark_ip_ecn_sctp_supported[RTE_COLOR_GREEN], 1370 cap.mark_ip_ecn_sctp_supported[RTE_COLOR_YELLOW], 1371 cap.mark_ip_ecn_sctp_supported[RTE_COLOR_RED]); 1372 printf("\t -- ip dscp: GREEN (%d) YELLOW (%d) RED (%d)\n", 1373 cap.mark_ip_dscp_supported[RTE_COLOR_GREEN], 1374 cap.mark_ip_dscp_supported[RTE_COLOR_YELLOW], 1375 cap.mark_ip_dscp_supported[RTE_COLOR_RED]); 1376 1377 printf(" - mask stats (0x%"PRIx64")" 1378 " dynamic update (0x%"PRIx64")\n", 1379 cap.stats_mask, 1380 cap.dynamic_update_mask); 1381 1382 printf(" - sched MAX:\n" 1383 "\t -- total (%u)\n" 1384 "\t -- sp levels (%u)\n" 1385 "\t -- wfq children per group (%u)\n" 1386 "\t -- wfq groups (%u)\n" 1387 "\t -- wfq weight (%u)\n", 1388 cap.sched_sp_n_priorities_max, 1389 cap.sched_sp_n_priorities_max, 1390 cap.sched_wfq_n_children_per_group_max, 1391 cap.sched_wfq_n_groups_max, 1392 cap.sched_wfq_weight_max); 1393 1394 printf(" - CMAN support:\n" 1395 "\t -- WRED mode: pkt (%d) byte (%d)\n" 1396 "\t -- head drop (%d)\n", 1397 cap.cman_wred_packet_mode_supported, 1398 cap.cman_wred_byte_mode_supported, 1399 cap.cman_head_drop_supported); 1400 printf("\t -- MAX WRED CONTEXT:" 1401 " total (%u) private (%u) shared (%u)\n", 1402 cap.cman_wred_context_n_max, 1403 cap.cman_wred_context_private_n_max, 1404 cap.cman_wred_context_shared_n_max); 1405 1406 for (j = 0; j < cap.n_nodes_max; j++) { 1407 memset(&capnode, 0, sizeof(capnode)); 1408 ret = rte_tm_node_capabilities_get(i, j, 1409 &capnode, &error); 1410 if (ret) 1411 continue; 1412 1413 check_for_leaf = 1; 1414 1415 printf(" NODE %u\n", j); 1416 printf("\t - shaper private: (%d) dual rate (%d)\n", 1417 capnode.shaper_private_supported, 1418 capnode.shaper_private_dual_rate_supported); 1419 printf("\t - shaper shared max: (%u)\n", 1420 capnode.shaper_shared_n_max); 1421 printf("\t - stats mask %"PRIx64"\n", 1422 capnode.stats_mask); 1423 1424 ret = rte_tm_node_type_get(i, j, &is_leaf, &error); 1425 if (ret) 1426 continue; 1427 1428 display_nodecap_info(is_leaf, &capnode); 1429 } 1430 1431 for (j = 0; j < cap.n_levels_max; j++) { 1432 memset(&caplevel, 0, sizeof(caplevel)); 1433 ret = rte_tm_level_capabilities_get(i, j, 1434 &caplevel, &error); 1435 if (ret) 1436 continue; 1437 1438 printf(" - Level %u\n", j); 1439 printf("\t -- node MAX: %u non leaf %u leaf %u\n", 1440 caplevel.n_nodes_max, 1441 caplevel.n_nodes_nonleaf_max, 1442 caplevel.n_nodes_leaf_max); 1443 printf("\t -- identical: non leaf %u leaf %u\n", 1444 caplevel.non_leaf_nodes_identical, 1445 caplevel.leaf_nodes_identical); 1446 1447 for (k = 0; k < caplevel.n_nodes_max; k++) { 1448 ret = rte_tm_node_type_get(i, k, 1449 &is_leaf, &error); 1450 if (ret) 1451 continue; 1452 1453 display_levelcap_info(is_leaf, &caplevel); 1454 } 1455 } 1456 1457 if (check_for_leaf) { 1458 ret = rte_tm_get_number_of_leaf_nodes(i, 1459 &n_leaf_nodes, &error); 1460 if (ret == 0) 1461 printf(" - leaf nodes (%u)\n", n_leaf_nodes); 1462 } 1463 1464 for (j = 0; j < n_leaf_nodes; j++) { 1465 struct rte_tm_node_stats stats; 1466 memset(&stats, 0, sizeof(stats)); 1467 1468 ret = rte_tm_node_stats_read(i, j, 1469 &stats, &cap.stats_mask, 0, &error); 1470 if (ret) 1471 continue; 1472 1473 printf(" - STATS for node (%u)\n", j); 1474 printf(" -- pkts (%"PRIu64") bytes (%"PRIu64")\n", 1475 stats.n_pkts, stats.n_bytes); 1476 1477 ret = rte_tm_node_type_get(i, j, &is_leaf, &error); 1478 if (ret || (!is_leaf)) 1479 continue; 1480 1481 printf(" -- leaf queued:" 1482 " pkts (%"PRIu64") bytes (%"PRIu64")\n", 1483 stats.leaf.n_pkts_queued, 1484 stats.leaf.n_bytes_queued); 1485 printf(" - dropped:\n" 1486 "\t -- GREEN:" 1487 " pkts (%"PRIu64") bytes (%"PRIu64")\n" 1488 "\t -- YELLOW:" 1489 " pkts (%"PRIu64") bytes (%"PRIu64")\n" 1490 "\t -- RED:" 1491 " pkts (%"PRIu64") bytes (%"PRIu64")\n", 1492 stats.leaf.n_pkts_dropped[RTE_COLOR_GREEN], 1493 stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN], 1494 stats.leaf.n_pkts_dropped[RTE_COLOR_YELLOW], 1495 stats.leaf.n_bytes_dropped[RTE_COLOR_YELLOW], 1496 stats.leaf.n_pkts_dropped[RTE_COLOR_RED], 1497 stats.leaf.n_bytes_dropped[RTE_COLOR_RED]); 1498 } 1499 } 1500 } 1501 1502 static void 1503 display_crypto_feature_info(uint64_t x) 1504 { 1505 if (x == 0) 1506 return; 1507 1508 printf("\t -- feature flags\n"); 1509 printf("\t\t + symmetric (%c), asymmetric (%c)\n" 1510 "\t\t + symmetric operation chaining (%c)\n", 1511 (x & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) ? 'y' : 'n', 1512 (x & RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO) ? 'y' : 'n', 1513 (x & RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING) ? 'y' : 'n'); 1514 printf("\t\t + CPU: SSE (%c), AVX (%c), AVX2 (%c), AVX512 (%c)\n", 1515 (x & RTE_CRYPTODEV_FF_CPU_SSE) ? 'y' : 'n', 1516 (x & RTE_CRYPTODEV_FF_CPU_AVX) ? 'y' : 'n', 1517 (x & RTE_CRYPTODEV_FF_CPU_AVX2) ? 'y' : 'n', 1518 (x & RTE_CRYPTODEV_FF_CPU_AVX512) ? 'y' : 'n'); 1519 printf("\t\t + AESNI: CPU (%c), HW (%c)\n", 1520 (x & RTE_CRYPTODEV_FF_CPU_AESNI) ? 'y' : 'n', 1521 (x & RTE_CRYPTODEV_FF_HW_ACCELERATED) ? 'y' : 'n'); 1522 printf("\t\t + SECURITY OFFLOAD (%c)\n", 1523 (x & RTE_CRYPTODEV_FF_SECURITY) ? 'y' : 'n'); 1524 printf("\t\t + ARM: NEON (%c), CE (%c)\n", 1525 (x & RTE_CRYPTODEV_FF_CPU_NEON) ? 'y' : 'n', 1526 (x & RTE_CRYPTODEV_FF_CPU_ARM_CE) ? 'y' : 'n'); 1527 printf("\t -- buffer offload\n"); 1528 printf("\t\t + IN_PLACE_SGL (%c)\n", 1529 (x & RTE_CRYPTODEV_FF_IN_PLACE_SGL) ? 'y' : 'n'); 1530 printf("\t\t + OOP_SGL_IN_SGL_OUT (%c)\n", 1531 (x & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT) ? 'y' : 'n'); 1532 printf("\t\t + OOP_SGL_IN_LB_OUT (%c)\n", 1533 (x & RTE_CRYPTODEV_FF_OOP_SGL_IN_LB_OUT) ? 'y' : 'n'); 1534 printf("\t\t + OOP_LB_IN_SGL_OUT (%c)\n", 1535 (x & RTE_CRYPTODEV_FF_OOP_LB_IN_SGL_OUT) ? 'y' : 'n'); 1536 printf("\t\t + OOP_LB_IN_LB_OUT (%c)\n", 1537 (x & RTE_CRYPTODEV_FF_OOP_LB_IN_LB_OUT) ? 'y' : 'n'); 1538 } 1539 1540 static void 1541 show_crypto(void) 1542 { 1543 uint8_t crypto_dev_count = rte_cryptodev_count(), i; 1544 1545 snprintf(bdr_str, MAX_STRING_LEN, " show - CRYPTO PMD "); 1546 STATS_BDR_STR(10, bdr_str); 1547 1548 for (i = 0; i < crypto_dev_count; i++) { 1549 struct rte_cryptodev_info dev_info; 1550 struct rte_cryptodev_stats stats; 1551 1552 rte_cryptodev_info_get(i, &dev_info); 1553 1554 printf(" - device (%u)\n", i); 1555 printf("\t -- name (%s)\n" 1556 "\t -- driver (%s)\n" 1557 "\t -- id (%u) on socket (%d)\n" 1558 "\t -- queue pairs (%d)\n", 1559 rte_cryptodev_name_get(i), 1560 dev_info.driver_name, 1561 dev_info.driver_id, 1562 rte_dev_numa_node(dev_info.device), 1563 rte_cryptodev_queue_pair_count(i)); 1564 1565 display_crypto_feature_info(dev_info.feature_flags); 1566 1567 if (rte_cryptodev_stats_get(i, &stats) == 0) { 1568 printf("\t -- stats\n"); 1569 printf("\t\t + enqueue count (%"PRIu64")" 1570 " error (%"PRIu64")\n", 1571 stats.enqueued_count, 1572 stats.enqueue_err_count); 1573 printf("\t\t + dequeue count (%"PRIu64")" 1574 " error (%"PRIu64")\n", 1575 stats.dequeued_count, 1576 stats.dequeue_err_count); 1577 } 1578 1579 #ifdef RTE_LIB_SECURITY 1580 show_security_context(i, false); 1581 #endif 1582 } 1583 } 1584 1585 static void 1586 show_ring(char *name) 1587 { 1588 snprintf(bdr_str, MAX_STRING_LEN, " show - RING "); 1589 STATS_BDR_STR(10, bdr_str); 1590 1591 if (name != NULL) { 1592 struct rte_ring *ptr = rte_ring_lookup(name); 1593 if (ptr != NULL) { 1594 printf(" - Name (%s) on socket (%d)\n" 1595 " - flags:\n" 1596 "\t -- Single Producer Enqueue (%u)\n" 1597 "\t -- Single Consumer Dequeue (%u)\n", 1598 ptr->name, 1599 ptr->memzone->socket_id, 1600 ptr->flags & RING_F_SP_ENQ, 1601 ptr->flags & RING_F_SC_DEQ); 1602 printf(" - size (%u) mask (0x%x) capacity (%u)\n", 1603 ptr->size, 1604 ptr->mask, 1605 ptr->capacity); 1606 printf(" - count (%u) free count (%u)\n", 1607 rte_ring_count(ptr), 1608 rte_ring_free_count(ptr)); 1609 printf(" - full (%d) empty (%d)\n", 1610 rte_ring_full(ptr), 1611 rte_ring_empty(ptr)); 1612 1613 STATS_BDR_STR(50, ""); 1614 return; 1615 } 1616 } 1617 1618 rte_ring_list_dump(stdout); 1619 } 1620 1621 static void 1622 show_mempool(char *name) 1623 { 1624 snprintf(bdr_str, MAX_STRING_LEN, " show - MEMPOOL "); 1625 STATS_BDR_STR(10, bdr_str); 1626 1627 if (name != NULL) { 1628 struct rte_mempool *ptr = rte_mempool_lookup(name); 1629 if (ptr != NULL) { 1630 struct rte_mempool_ops *ops; 1631 uint64_t flags = ptr->flags; 1632 1633 ops = rte_mempool_get_ops(ptr->ops_index); 1634 printf(" - Name: %s on socket %d\n" 1635 " - flags:\n" 1636 "\t -- No spread (%c)\n" 1637 "\t -- No cache align (%c)\n" 1638 "\t -- SP put (%c), SC get (%c)\n" 1639 "\t -- Pool created (%c)\n" 1640 "\t -- No IOVA config (%c)\n" 1641 "\t -- Not used for IO (%c)\n", 1642 ptr->name, 1643 ptr->socket_id, 1644 (flags & RTE_MEMPOOL_F_NO_SPREAD) ? 'y' : 'n', 1645 (flags & RTE_MEMPOOL_F_NO_CACHE_ALIGN) ? 'y' : 'n', 1646 (flags & RTE_MEMPOOL_F_SP_PUT) ? 'y' : 'n', 1647 (flags & RTE_MEMPOOL_F_SC_GET) ? 'y' : 'n', 1648 (flags & RTE_MEMPOOL_F_POOL_CREATED) ? 'y' : 'n', 1649 (flags & RTE_MEMPOOL_F_NO_IOVA_CONTIG) ? 'y' : 'n', 1650 (flags & RTE_MEMPOOL_F_NON_IO) ? 'y' : 'n'); 1651 printf(" - Size %u Cache %u element %u\n" 1652 " - header %u trailer %u\n" 1653 " - private data size %u\n", 1654 ptr->size, 1655 ptr->cache_size, 1656 ptr->elt_size, 1657 ptr->header_size, 1658 ptr->trailer_size, 1659 ptr->private_data_size); 1660 printf(" - memezone - socket %d\n", 1661 ptr->mz->socket_id); 1662 printf(" - Count: avail (%u), in use (%u)\n", 1663 rte_mempool_avail_count(ptr), 1664 rte_mempool_in_use_count(ptr)); 1665 printf(" - ops_index %d ops_name %s\n", 1666 ptr->ops_index, ops ? ops->name : "NA"); 1667 1668 return; 1669 } 1670 } 1671 1672 rte_mempool_list_dump(stdout); 1673 } 1674 1675 static void 1676 mempool_itr_obj(struct rte_mempool *mp, void *opaque, 1677 void *obj, unsigned int obj_idx) 1678 { 1679 printf(" - obj_idx %u opaque %p obj %p\n", 1680 obj_idx, opaque, obj); 1681 1682 if (obj) 1683 rte_hexdump(stdout, " Obj Content", 1684 obj, (mp->elt_size > 256)?256:mp->elt_size); 1685 } 1686 1687 static void 1688 iter_mempool(char *name) 1689 { 1690 snprintf(bdr_str, MAX_STRING_LEN, " iter - MEMPOOL "); 1691 STATS_BDR_STR(10, bdr_str); 1692 1693 if (name != NULL) { 1694 struct rte_mempool *ptr = rte_mempool_lookup(name); 1695 if (ptr != NULL) { 1696 /* iterate each object */ 1697 uint32_t ret = rte_mempool_obj_iter(ptr, 1698 mempool_itr_obj, NULL); 1699 printf("\n - iterated %u objects\n", ret); 1700 return; 1701 } 1702 } 1703 } 1704 1705 static void 1706 dump_regs(char *file_prefix) 1707 { 1708 #define MAX_FILE_NAME_SZ (MAX_LONG_OPT_SZ + 10) 1709 char file_name[MAX_FILE_NAME_SZ]; 1710 struct rte_dev_reg_info reg_info; 1711 struct rte_eth_dev_info dev_info; 1712 unsigned char *buf_data; 1713 size_t buf_size; 1714 FILE *fp_regs; 1715 uint16_t i; 1716 int ret; 1717 1718 snprintf(bdr_str, MAX_STRING_LEN, " dump - Port REG"); 1719 STATS_BDR_STR(10, bdr_str); 1720 1721 RTE_ETH_FOREACH_DEV(i) { 1722 /* Skip if port is not in mask */ 1723 if ((enabled_port_mask & (1ul << i)) == 0) 1724 continue; 1725 1726 snprintf(bdr_str, MAX_STRING_LEN, " Port (%u)", i); 1727 STATS_BDR_STR(5, bdr_str); 1728 1729 ret = rte_eth_dev_info_get(i, &dev_info); 1730 if (ret) { 1731 printf("Error getting device info: %d\n", ret); 1732 continue; 1733 } 1734 1735 memset(®_info, 0, sizeof(reg_info)); 1736 ret = rte_eth_dev_get_reg_info(i, ®_info); 1737 if (ret) { 1738 printf("Error getting device reg info: %d\n", ret); 1739 continue; 1740 } 1741 1742 buf_size = reg_info.length * reg_info.width; 1743 buf_data = malloc(buf_size); 1744 if (buf_data == NULL) { 1745 printf("Error allocating %zu bytes buffer\n", buf_size); 1746 continue; 1747 } 1748 1749 reg_info.data = buf_data; 1750 reg_info.length = 0; 1751 ret = rte_eth_dev_get_reg_info(i, ®_info); 1752 if (ret) { 1753 printf("Error getting regs from device: %d\n", ret); 1754 free(buf_data); 1755 continue; 1756 } 1757 1758 snprintf(file_name, MAX_FILE_NAME_SZ, "%s-port%u", 1759 file_prefix, i); 1760 fp_regs = fopen(file_name, "wb"); 1761 if (fp_regs == NULL) { 1762 printf("Error during opening '%s' for writing: %s\n", 1763 file_name, strerror(errno)); 1764 } else { 1765 size_t nr_written; 1766 1767 nr_written = fwrite(buf_data, 1, buf_size, fp_regs); 1768 if (nr_written != buf_size) 1769 printf("Error during writing %s: %s\n", 1770 file_prefix, strerror(errno)); 1771 else 1772 printf("Device (%s) regs dumped successfully, " 1773 "driver:%s version:0X%08X\n", 1774 rte_dev_name(dev_info.device), 1775 dev_info.driver_name, reg_info.version); 1776 1777 fclose(fp_regs); 1778 } 1779 1780 free(buf_data); 1781 } 1782 } 1783 1784 static void 1785 show_version(void) 1786 { 1787 snprintf(bdr_str, MAX_STRING_LEN, " show - DPDK version "); 1788 STATS_BDR_STR(10, bdr_str); 1789 printf("DPDK version: %s\n", rte_version()); 1790 } 1791 1792 static void 1793 show_firmware_version(void) 1794 { 1795 char fw_version[ETHDEV_FWVERS_LEN]; 1796 uint16_t i; 1797 1798 snprintf(bdr_str, MAX_STRING_LEN, " show - firmware version "); 1799 STATS_BDR_STR(10, bdr_str); 1800 1801 RTE_ETH_FOREACH_DEV(i) { 1802 /* Skip if port is not in mask */ 1803 if ((enabled_port_mask & (1ul << i)) == 0) 1804 continue; 1805 1806 if (rte_eth_dev_fw_version_get(i, fw_version, 1807 ETHDEV_FWVERS_LEN) == 0) 1808 printf("Ethdev port %u firmware version: %s\n", i, 1809 fw_version); 1810 else 1811 printf("Ethdev port %u firmware version: %s\n", i, 1812 "not available"); 1813 } 1814 } 1815 1816 static void 1817 show_port_rss_reta_info(void) 1818 { 1819 struct rte_eth_rss_reta_entry64 reta_conf[RTE_RETA_CONF_GROUP_NUM + 1]; 1820 struct rte_eth_dev_info dev_info; 1821 uint16_t i, idx, shift; 1822 uint16_t num; 1823 uint16_t id; 1824 int ret; 1825 1826 RTE_ETH_FOREACH_DEV(id) { 1827 /* Skip if port is not in mask */ 1828 if ((enabled_port_mask & (1ul << id)) == 0) 1829 continue; 1830 1831 snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", id); 1832 STATS_BDR_STR(5, bdr_str); 1833 1834 ret = rte_eth_dev_info_get(id, &dev_info); 1835 if (ret != 0) { 1836 fprintf(stderr, "Error getting device info: %s\n", 1837 strerror(-ret)); 1838 return; 1839 } 1840 1841 num = DIV_ROUND_UP(dev_info.reta_size, RTE_ETH_RETA_GROUP_SIZE); 1842 memset(reta_conf, 0, sizeof(reta_conf)); 1843 for (i = 0; i < num; i++) 1844 reta_conf[i].mask = ~0ULL; 1845 1846 ret = rte_eth_dev_rss_reta_query(id, reta_conf, dev_info.reta_size); 1847 if (ret != 0) { 1848 fprintf(stderr, "Error getting RSS RETA info: %s\n", 1849 strerror(-ret)); 1850 return; 1851 } 1852 1853 for (i = 0; i < dev_info.reta_size; i++) { 1854 idx = i / RTE_ETH_RETA_GROUP_SIZE; 1855 shift = i % RTE_ETH_RETA_GROUP_SIZE; 1856 printf("RSS RETA configuration: hash index=%u, queue=%u\n", 1857 i, reta_conf[idx].reta[shift]); 1858 } 1859 } 1860 } 1861 1862 static void 1863 show_module_eeprom_info(void) 1864 { 1865 unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE]; 1866 struct rte_eth_dev_module_info module_info; 1867 struct rte_dev_eeprom_info eeprom_info; 1868 uint16_t i; 1869 int ret; 1870 1871 RTE_ETH_FOREACH_DEV(i) { 1872 /* Skip if port is not in mask */ 1873 if ((enabled_port_mask & (1ul << i)) == 0) 1874 continue; 1875 1876 snprintf(bdr_str, MAX_STRING_LEN, " Port %u ", i); 1877 STATS_BDR_STR(5, bdr_str); 1878 1879 ret = rte_eth_dev_get_module_info(i, &module_info); 1880 if (ret != 0) { 1881 fprintf(stderr, "Module EEPROM information read error: %s\n", 1882 strerror(-ret)); 1883 return; 1884 } 1885 1886 eeprom_info.offset = 0; 1887 eeprom_info.length = module_info.eeprom_len; 1888 eeprom_info.data = bytes_eeprom; 1889 1890 ret = rte_eth_dev_get_module_eeprom(i, &eeprom_info); 1891 if (ret != 0) { 1892 fprintf(stderr, "Module EEPROM read error: %s\n", 1893 strerror(-ret)); 1894 return; 1895 } 1896 1897 rte_hexdump(stdout, "hexdump", eeprom_info.data, 1898 eeprom_info.length); 1899 printf("Finish -- Port: %u MODULE EEPROM length: %d bytes\n", 1900 i, eeprom_info.length); 1901 } 1902 } 1903 1904 static void 1905 nic_rx_descriptor_display(uint16_t port_id, struct desc_param *desc) 1906 { 1907 uint16_t queue_id = desc->queue_id; 1908 uint16_t offset = desc->offset; 1909 uint16_t num = desc->num; 1910 int ret; 1911 1912 snprintf(bdr_str, MAX_STRING_LEN, " show - Rx descriptor "); 1913 STATS_BDR_STR(10, bdr_str); 1914 1915 printf("Dump ethdev Rx descriptor for port %u, queue %u, offset %u, num %u\n", 1916 port_id, queue_id, offset, num); 1917 1918 ret = rte_eth_rx_descriptor_dump(port_id, queue_id, offset, num, 1919 stdout); 1920 if (ret < 0) 1921 fprintf(stderr, "Error dumping ethdev Rx descriptor: %s\n", 1922 strerror(-ret)); 1923 } 1924 1925 static void 1926 nic_tx_descriptor_display(uint16_t port_id, struct desc_param *desc) 1927 { 1928 uint16_t queue_id = desc->queue_id; 1929 uint16_t offset = desc->offset; 1930 uint16_t num = desc->num; 1931 int ret; 1932 1933 snprintf(bdr_str, MAX_STRING_LEN, " show - Tx descriptor "); 1934 STATS_BDR_STR(10, bdr_str); 1935 1936 printf("Dump ethdev Tx descriptor for port %u, queue %u, offset %u, num %u\n", 1937 port_id, queue_id, offset, num); 1938 1939 ret = rte_eth_tx_descriptor_dump(port_id, queue_id, offset, num, 1940 stdout); 1941 if (ret < 0) 1942 fprintf(stderr, "Error dumping ethdev Tx descriptor: %s\n", 1943 strerror(-ret)); 1944 } 1945 1946 static void 1947 xstats_display(uint8_t dev_id, 1948 enum rte_event_dev_xstats_mode mode, 1949 uint8_t queue_port_id) 1950 { 1951 int ret; 1952 struct rte_event_dev_xstats_name *xstats_names; 1953 uint64_t *ids; 1954 uint64_t *values; 1955 int size; 1956 int i; 1957 1958 size = rte_event_dev_xstats_names_get(dev_id, 1959 mode, 1960 queue_port_id, 1961 NULL, /* names */ 1962 NULL, /* ids */ 1963 0); /* num */ 1964 1965 if (size < 0) 1966 rte_panic("rte_event_dev_xstats_names_get err %d\n", size); 1967 1968 if (size == 0) { 1969 printf( 1970 "No stats available for this item, mode=%d, queue_port_id=%d\n", 1971 mode, queue_port_id); 1972 return; 1973 } 1974 1975 /* Get memory to hold stat names, IDs, and values */ 1976 xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size); 1977 ids = malloc(sizeof(unsigned int) * size); 1978 1979 if (!xstats_names || !ids) 1980 rte_panic("unable to alloc memory for stats retrieval\n"); 1981 1982 ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id, 1983 xstats_names, ids, 1984 (unsigned int)size); 1985 if (ret != size) 1986 rte_panic("rte_event_dev_xstats_names_get err %d\n", ret); 1987 1988 values = malloc(sizeof(uint64_t) * size); 1989 if (!values) 1990 rte_panic("unable to alloc memory for stats retrieval\n"); 1991 1992 ret = rte_event_dev_xstats_get(dev_id, mode, queue_port_id, 1993 ids, values, size); 1994 1995 if (ret != size) 1996 rte_panic("rte_event_dev_xstats_get err %d\n", ret); 1997 1998 for (i = 0; i < size; i++) { 1999 printf("id %"PRIu64" %s = %"PRIu64"\n", 2000 ids[i], &xstats_names[i].name[0], values[i]); 2001 } 2002 2003 free(values); 2004 free(xstats_names); 2005 free(ids); 2006 2007 } 2008 2009 static void 2010 xstats_reset(uint8_t dev_id, 2011 enum rte_event_dev_xstats_mode mode, 2012 uint8_t queue_port_id) 2013 { 2014 int ret; 2015 struct rte_event_dev_xstats_name *xstats_names; 2016 uint64_t *ids; 2017 int size; 2018 2019 size = rte_event_dev_xstats_names_get(dev_id, 2020 mode, 2021 queue_port_id, 2022 NULL, /* names */ 2023 NULL, /* ids */ 2024 0); /* num */ 2025 2026 if (size < 0) 2027 rte_panic("rte_event_dev_xstats_names_get err %d\n", size); 2028 2029 if (size == 0) { 2030 printf( 2031 "No stats available for this item, mode=%d, queue_port_id=%d\n", 2032 mode, queue_port_id); 2033 return; 2034 } 2035 2036 /* Get memory to hold stat names, IDs, and values */ 2037 xstats_names = malloc(sizeof(struct rte_event_dev_xstats_name) * (unsigned int)size); 2038 ids = malloc(sizeof(unsigned int) * size); 2039 2040 if (!xstats_names || !ids) 2041 rte_panic("unable to alloc memory for stats retrieval\n"); 2042 2043 ret = rte_event_dev_xstats_names_get(dev_id, mode, queue_port_id, 2044 xstats_names, ids, 2045 (unsigned int)size); 2046 if (ret != size) 2047 rte_panic("rte_event_dev_xstats_names_get err %d\n", ret); 2048 2049 rte_event_dev_xstats_reset(dev_id, mode, queue_port_id, 2050 ids, size); 2051 2052 free(xstats_names); 2053 free(ids); 2054 2055 } 2056 2057 static unsigned int 2058 eventdev_xstats(void) 2059 { 2060 unsigned int count = 0; 2061 int i, j; 2062 2063 for (i = 0; i < rte_event_dev_count(); i++) { 2064 2065 if (eventdev_var[i].dump_xstats) { 2066 ++count; 2067 int ret = rte_event_dev_dump(i, stdout); 2068 2069 if (ret) 2070 rte_panic("dump failed with err=%d\n", ret); 2071 } 2072 2073 if (eventdev_var[i].shw_device_xstats == 1) { 2074 ++count; 2075 xstats_display(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0); 2076 2077 if (eventdev_var[i].reset_xstats == 1) 2078 xstats_reset(i, RTE_EVENT_DEV_XSTATS_DEVICE, 0); 2079 } 2080 2081 if (eventdev_var[i].shw_all_ports == 1) { 2082 ++count; 2083 for (j = 0; j < MAX_PORTS_QUEUES; j++) { 2084 xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT, j); 2085 2086 if (eventdev_var[i].reset_xstats == 1) 2087 xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT, j); 2088 } 2089 } else { 2090 if (eventdev_var[i].num_ports > 0) 2091 ++count; 2092 for (j = 0; j < eventdev_var[i].num_ports; j++) { 2093 xstats_display(i, RTE_EVENT_DEV_XSTATS_PORT, 2094 eventdev_var[i].ports[j]); 2095 2096 if (eventdev_var[i].reset_xstats == 1) 2097 xstats_reset(i, RTE_EVENT_DEV_XSTATS_PORT, 2098 eventdev_var[i].ports[j]); 2099 } 2100 } 2101 2102 if (eventdev_var[i].shw_all_queues == 1) { 2103 ++count; 2104 for (j = 0; j < MAX_PORTS_QUEUES; j++) { 2105 xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE, j); 2106 2107 if (eventdev_var[i].reset_xstats == 1) 2108 xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE, j); 2109 } 2110 } else { 2111 if (eventdev_var[i].num_queues > 0) 2112 ++count; 2113 for (j = 0; j < eventdev_var[i].num_queues; j++) { 2114 xstats_display(i, RTE_EVENT_DEV_XSTATS_QUEUE, 2115 eventdev_var[i].queues[j]); 2116 2117 if (eventdev_var[i].reset_xstats == 1) 2118 xstats_reset(i, RTE_EVENT_DEV_XSTATS_QUEUE, 2119 eventdev_var[i].queues[j]); 2120 } 2121 } 2122 } 2123 2124 return count; 2125 } 2126 2127 int 2128 main(int argc, char **argv) 2129 { 2130 int ret; 2131 int i; 2132 char c_flag[] = "-c1"; 2133 char n_flag[] = "-n4"; 2134 char mp_flag[] = "--proc-type=secondary"; 2135 char log_flag[] = "--log-level=6"; 2136 char *argp[argc + 4]; 2137 uint16_t nb_ports; 2138 2139 /* preparse app arguments */ 2140 ret = proc_info_preparse_args(argc, argv); 2141 if (ret < 0) { 2142 printf("Failed to parse arguments\n"); 2143 return -1; 2144 } 2145 2146 argp[0] = argv[0]; 2147 argp[1] = c_flag; 2148 argp[2] = n_flag; 2149 argp[3] = mp_flag; 2150 argp[4] = log_flag; 2151 2152 for (i = 1; i < argc; i++) 2153 argp[i + 4] = argv[i]; 2154 2155 argc += 4; 2156 2157 ret = rte_eal_init(argc, argp); 2158 if (ret < 0) 2159 rte_panic("Cannot init EAL\n"); 2160 2161 argc -= ret; 2162 argv += ret - 4; 2163 2164 if (!rte_eal_primary_proc_alive(NULL)) 2165 rte_exit(EXIT_FAILURE, "No primary DPDK process is running.\n"); 2166 2167 /* parse app arguments */ 2168 ret = proc_info_parse_args(argc, argv); 2169 if (ret < 0) 2170 rte_exit(EXIT_FAILURE, "Invalid argument\n"); 2171 2172 if (mem_info) { 2173 meminfo_display(); 2174 goto cleanup; 2175 } 2176 2177 if (eventdev_xstats() > 0) 2178 goto cleanup; 2179 2180 nb_ports = rte_eth_dev_count_avail(); 2181 if (nb_ports == 0) 2182 rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); 2183 2184 /* If no port mask was specified, then show all non-owned ports */ 2185 if (enabled_port_mask == 0) { 2186 RTE_ETH_FOREACH_DEV(i) 2187 enabled_port_mask |= 1ul << i; 2188 } 2189 2190 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 2191 2192 /* Skip if port is not in mask */ 2193 if ((enabled_port_mask & (1ul << i)) == 0) 2194 continue; 2195 2196 /* Skip if port is unused */ 2197 if (!rte_eth_dev_is_valid_port(i)) 2198 continue; 2199 2200 if (enable_stats) 2201 nic_stats_display(i); 2202 else if (enable_xstats) 2203 nic_xstats_display(i); 2204 else if (reset_stats) 2205 nic_stats_clear(i); 2206 else if (reset_xstats) 2207 nic_xstats_clear(i); 2208 else if (enable_xstats_name) 2209 nic_xstats_by_name_display(i, xstats_name); 2210 else if (nb_xstats_ids > 0) 2211 nic_xstats_by_ids_display(i, xstats_ids, 2212 nb_xstats_ids); 2213 #ifdef RTE_LIB_METRICS 2214 else if (enable_metrics) 2215 metrics_display(i); 2216 #endif 2217 2218 if (enable_shw_rx_desc_dump) 2219 nic_rx_descriptor_display(i, &rx_desc_param); 2220 if (enable_shw_tx_desc_dump) 2221 nic_tx_descriptor_display(i, &tx_desc_param); 2222 } 2223 2224 #ifdef RTE_LIB_METRICS 2225 /* print port independent stats */ 2226 if (enable_metrics) 2227 metrics_display(RTE_METRICS_GLOBAL); 2228 #endif 2229 2230 /* show information for PMD */ 2231 if (enable_shw_port) 2232 show_port(); 2233 if (enable_shw_port_priv) 2234 show_port_private_info(); 2235 if (enable_shw_tm) 2236 show_tm(); 2237 if (enable_shw_crypto) 2238 show_crypto(); 2239 if (enable_shw_ring) 2240 show_ring(ring_name); 2241 if (enable_shw_mempool) 2242 show_mempool(mempool_name); 2243 if (enable_iter_mempool) 2244 iter_mempool(mempool_iter_name); 2245 if (enable_dump_regs) 2246 dump_regs(dump_regs_file_prefix); 2247 if (enable_shw_version) 2248 show_version(); 2249 if (enable_shw_fw_version) 2250 show_firmware_version(); 2251 if (enable_shw_rss_reta) 2252 show_port_rss_reta_info(); 2253 if (enable_shw_module_eeprom) 2254 show_module_eeprom_info(); 2255 2256 RTE_ETH_FOREACH_DEV(i) 2257 rte_eth_dev_close(i); 2258 2259 cleanup: 2260 ret = rte_eal_cleanup(); 2261 if (ret) 2262 printf("Error from rte_eal_cleanup(), %d\n", ret); 2263 2264 return 0; 2265 } 2266