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