1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2017 Intel Corporation 3 */ 4 5 #include <stdarg.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <signal.h> 9 #include <string.h> 10 #include <time.h> 11 #include <fcntl.h> 12 #include <sys/mman.h> 13 #include <sys/types.h> 14 #include <errno.h> 15 16 #include <sys/queue.h> 17 #include <sys/stat.h> 18 19 #include <stdint.h> 20 #include <unistd.h> 21 #include <inttypes.h> 22 23 #include <rte_common.h> 24 #include <rte_errno.h> 25 #include <rte_byteorder.h> 26 #include <rte_log.h> 27 #include <rte_debug.h> 28 #include <rte_cycles.h> 29 #include <rte_memory.h> 30 #include <rte_memcpy.h> 31 #include <rte_launch.h> 32 #include <rte_eal.h> 33 #include <rte_alarm.h> 34 #include <rte_per_lcore.h> 35 #include <rte_lcore.h> 36 #include <rte_atomic.h> 37 #include <rte_branch_prediction.h> 38 #include <rte_mempool.h> 39 #include <rte_malloc.h> 40 #include <rte_mbuf.h> 41 #include <rte_mbuf_pool_ops.h> 42 #include <rte_interrupts.h> 43 #include <rte_pci.h> 44 #include <rte_ether.h> 45 #include <rte_ethdev.h> 46 #include <rte_dev.h> 47 #include <rte_string_fns.h> 48 #ifdef RTE_LIBRTE_IXGBE_PMD 49 #include <rte_pmd_ixgbe.h> 50 #endif 51 #ifdef RTE_LIBRTE_PDUMP 52 #include <rte_pdump.h> 53 #endif 54 #include <rte_flow.h> 55 #include <rte_metrics.h> 56 #ifdef RTE_LIBRTE_BITRATE 57 #include <rte_bitrate.h> 58 #endif 59 #ifdef RTE_LIBRTE_LATENCY_STATS 60 #include <rte_latencystats.h> 61 #endif 62 63 #include "testpmd.h" 64 65 uint16_t verbose_level = 0; /**< Silent by default. */ 66 int testpmd_logtype; /**< Log type for testpmd logs */ 67 68 /* use master core for command line ? */ 69 uint8_t interactive = 0; 70 uint8_t auto_start = 0; 71 uint8_t tx_first; 72 char cmdline_filename[PATH_MAX] = {0}; 73 74 /* 75 * NUMA support configuration. 76 * When set, the NUMA support attempts to dispatch the allocation of the 77 * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 78 * probed ports among the CPU sockets 0 and 1. 79 * Otherwise, all memory is allocated from CPU socket 0. 80 */ 81 uint8_t numa_support = 1; /**< numa enabled by default */ 82 83 /* 84 * In UMA mode,all memory is allocated from socket 0 if --socket-num is 85 * not configured. 86 */ 87 uint8_t socket_num = UMA_NO_CONFIG; 88 89 /* 90 * Use ANONYMOUS mapped memory (might be not physically continuous) for mbufs. 91 */ 92 uint8_t mp_anon = 0; 93 94 /* 95 * Store specified sockets on which memory pool to be used by ports 96 * is allocated. 97 */ 98 uint8_t port_numa[RTE_MAX_ETHPORTS]; 99 100 /* 101 * Store specified sockets on which RX ring to be used by ports 102 * is allocated. 103 */ 104 uint8_t rxring_numa[RTE_MAX_ETHPORTS]; 105 106 /* 107 * Store specified sockets on which TX ring to be used by ports 108 * is allocated. 109 */ 110 uint8_t txring_numa[RTE_MAX_ETHPORTS]; 111 112 /* 113 * Record the Ethernet address of peer target ports to which packets are 114 * forwarded. 115 * Must be instantiated with the ethernet addresses of peer traffic generator 116 * ports. 117 */ 118 struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 119 portid_t nb_peer_eth_addrs = 0; 120 121 /* 122 * Probed Target Environment. 123 */ 124 struct rte_port *ports; /**< For all probed ethernet ports. */ 125 portid_t nb_ports; /**< Number of probed ethernet ports. */ 126 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 127 lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 128 129 /* 130 * Test Forwarding Configuration. 131 * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 132 * nb_fwd_ports <= nb_cfg_ports <= nb_ports 133 */ 134 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 135 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 136 portid_t nb_cfg_ports; /**< Number of configured ports. */ 137 portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 138 139 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 140 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 141 142 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 143 streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 144 145 /* 146 * Forwarding engines. 147 */ 148 struct fwd_engine * fwd_engines[] = { 149 &io_fwd_engine, 150 &mac_fwd_engine, 151 &mac_swap_engine, 152 &flow_gen_engine, 153 &rx_only_engine, 154 &tx_only_engine, 155 &csum_fwd_engine, 156 &icmp_echo_engine, 157 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED 158 &softnic_tm_engine, 159 &softnic_tm_bypass_engine, 160 #endif 161 #ifdef RTE_LIBRTE_IEEE1588 162 &ieee1588_fwd_engine, 163 #endif 164 NULL, 165 }; 166 167 struct fwd_config cur_fwd_config; 168 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 169 uint32_t retry_enabled; 170 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; 171 uint32_t burst_tx_retry_num = BURST_TX_RETRIES; 172 173 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 174 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 175 * specified on command-line. */ 176 uint16_t stats_period; /**< Period to show statistics (disabled by default) */ 177 178 /* 179 * In container, it cannot terminate the process which running with 'stats-period' 180 * option. Set flag to exit stats period loop after received SIGINT/SIGTERM. 181 */ 182 uint8_t f_quit; 183 184 /* 185 * Configuration of packet segments used by the "txonly" processing engine. 186 */ 187 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 188 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 189 TXONLY_DEF_PACKET_LEN, 190 }; 191 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 192 193 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF; 194 /**< Split policy for packets to TX. */ 195 196 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 197 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ 198 199 /* current configuration is in DCB or not,0 means it is not in DCB mode */ 200 uint8_t dcb_config = 0; 201 202 /* Whether the dcb is in testing status */ 203 uint8_t dcb_test = 0; 204 205 /* 206 * Configurable number of RX/TX queues. 207 */ 208 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 209 queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 210 211 /* 212 * Configurable number of RX/TX ring descriptors. 213 */ 214 #define RTE_TEST_RX_DESC_DEFAULT 1024 215 #define RTE_TEST_TX_DESC_DEFAULT 1024 216 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 217 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 218 219 #define RTE_PMD_PARAM_UNSET -1 220 /* 221 * Configurable values of RX and TX ring threshold registers. 222 */ 223 224 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET; 225 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET; 226 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET; 227 228 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET; 229 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET; 230 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET; 231 232 /* 233 * Configurable value of RX free threshold. 234 */ 235 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET; 236 237 /* 238 * Configurable value of RX drop enable. 239 */ 240 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET; 241 242 /* 243 * Configurable value of TX free threshold. 244 */ 245 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET; 246 247 /* 248 * Configurable value of TX RS bit threshold. 249 */ 250 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET; 251 252 /* 253 * Receive Side Scaling (RSS) configuration. 254 */ 255 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */ 256 257 /* 258 * Port topology configuration 259 */ 260 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 261 262 /* 263 * Avoids to flush all the RX streams before starts forwarding. 264 */ 265 uint8_t no_flush_rx = 0; /* flush by default */ 266 267 /* 268 * Flow API isolated mode. 269 */ 270 uint8_t flow_isolate_all; 271 272 /* 273 * Avoids to check link status when starting/stopping a port. 274 */ 275 uint8_t no_link_check = 0; /* check by default */ 276 277 /* 278 * Enable link status change notification 279 */ 280 uint8_t lsc_interrupt = 1; /* enabled by default */ 281 282 /* 283 * Enable device removal notification. 284 */ 285 uint8_t rmv_interrupt = 1; /* enabled by default */ 286 287 /* 288 * Display or mask ether events 289 * Default to all events except VF_MBOX 290 */ 291 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) | 292 (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) | 293 (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) | 294 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) | 295 (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) | 296 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV); 297 298 /* 299 * NIC bypass mode configuration options. 300 */ 301 302 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS 303 /* The NIC bypass watchdog timeout. */ 304 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF; 305 #endif 306 307 308 #ifdef RTE_LIBRTE_LATENCY_STATS 309 310 /* 311 * Set when latency stats is enabled in the commandline 312 */ 313 uint8_t latencystats_enabled; 314 315 /* 316 * Lcore ID to serive latency statistics. 317 */ 318 lcoreid_t latencystats_lcore_id = -1; 319 320 #endif 321 322 /* 323 * Ethernet device configuration. 324 */ 325 struct rte_eth_rxmode rx_mode = { 326 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */ 327 .offloads = DEV_RX_OFFLOAD_CRC_STRIP, 328 .ignore_offload_bitfield = 1, 329 }; 330 331 struct rte_eth_txmode tx_mode = { 332 .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE, 333 }; 334 335 struct rte_fdir_conf fdir_conf = { 336 .mode = RTE_FDIR_MODE_NONE, 337 .pballoc = RTE_FDIR_PBALLOC_64K, 338 .status = RTE_FDIR_REPORT_STATUS, 339 .mask = { 340 .vlan_tci_mask = 0x0, 341 .ipv4_mask = { 342 .src_ip = 0xFFFFFFFF, 343 .dst_ip = 0xFFFFFFFF, 344 }, 345 .ipv6_mask = { 346 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 347 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 348 }, 349 .src_port_mask = 0xFFFF, 350 .dst_port_mask = 0xFFFF, 351 .mac_addr_byte_mask = 0xFF, 352 .tunnel_type_mask = 1, 353 .tunnel_id_mask = 0xFFFFFFFF, 354 }, 355 .drop_queue = 127, 356 }; 357 358 volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 359 360 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 361 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 362 363 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 364 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 365 366 uint16_t nb_tx_queue_stats_mappings = 0; 367 uint16_t nb_rx_queue_stats_mappings = 0; 368 369 /* 370 * Display zero values by default for xstats 371 */ 372 uint8_t xstats_hide_zero; 373 374 unsigned int num_sockets = 0; 375 unsigned int socket_ids[RTE_MAX_NUMA_NODES]; 376 377 #ifdef RTE_LIBRTE_BITRATE 378 /* Bitrate statistics */ 379 struct rte_stats_bitrates *bitrate_data; 380 lcoreid_t bitrate_lcore_id; 381 uint8_t bitrate_enabled; 382 #endif 383 384 struct gro_status gro_ports[RTE_MAX_ETHPORTS]; 385 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES; 386 387 /* Forward function declarations */ 388 static void map_port_queue_stats_mapping_registers(portid_t pi, 389 struct rte_port *port); 390 static void check_all_ports_link_status(uint32_t port_mask); 391 static int eth_event_callback(portid_t port_id, 392 enum rte_eth_event_type type, 393 void *param, void *ret_param); 394 395 /* 396 * Check if all the ports are started. 397 * If yes, return positive value. If not, return zero. 398 */ 399 static int all_ports_started(void); 400 401 struct gso_status gso_ports[RTE_MAX_ETHPORTS]; 402 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN; 403 404 /* 405 * Helper function to check if socket is already discovered. 406 * If yes, return positive value. If not, return zero. 407 */ 408 int 409 new_socket_id(unsigned int socket_id) 410 { 411 unsigned int i; 412 413 for (i = 0; i < num_sockets; i++) { 414 if (socket_ids[i] == socket_id) 415 return 0; 416 } 417 return 1; 418 } 419 420 /* 421 * Setup default configuration. 422 */ 423 static void 424 set_default_fwd_lcores_config(void) 425 { 426 unsigned int i; 427 unsigned int nb_lc; 428 unsigned int sock_num; 429 430 nb_lc = 0; 431 for (i = 0; i < RTE_MAX_LCORE; i++) { 432 sock_num = rte_lcore_to_socket_id(i); 433 if (new_socket_id(sock_num)) { 434 if (num_sockets >= RTE_MAX_NUMA_NODES) { 435 rte_exit(EXIT_FAILURE, 436 "Total sockets greater than %u\n", 437 RTE_MAX_NUMA_NODES); 438 } 439 socket_ids[num_sockets++] = sock_num; 440 } 441 if (!rte_lcore_is_enabled(i)) 442 continue; 443 if (i == rte_get_master_lcore()) 444 continue; 445 fwd_lcores_cpuids[nb_lc++] = i; 446 } 447 nb_lcores = (lcoreid_t) nb_lc; 448 nb_cfg_lcores = nb_lcores; 449 nb_fwd_lcores = 1; 450 } 451 452 static void 453 set_def_peer_eth_addrs(void) 454 { 455 portid_t i; 456 457 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 458 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR; 459 peer_eth_addrs[i].addr_bytes[5] = i; 460 } 461 } 462 463 static void 464 set_default_fwd_ports_config(void) 465 { 466 portid_t pt_id; 467 int i = 0; 468 469 RTE_ETH_FOREACH_DEV(pt_id) 470 fwd_ports_ids[i++] = pt_id; 471 472 nb_cfg_ports = nb_ports; 473 nb_fwd_ports = nb_ports; 474 } 475 476 void 477 set_def_fwd_config(void) 478 { 479 set_default_fwd_lcores_config(); 480 set_def_peer_eth_addrs(); 481 set_default_fwd_ports_config(); 482 } 483 484 /* 485 * Configuration initialisation done once at init time. 486 */ 487 static void 488 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 489 unsigned int socket_id) 490 { 491 char pool_name[RTE_MEMPOOL_NAMESIZE]; 492 struct rte_mempool *rte_mp = NULL; 493 uint32_t mb_size; 494 495 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; 496 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 497 498 TESTPMD_LOG(INFO, 499 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", 500 pool_name, nb_mbuf, mbuf_seg_size, socket_id); 501 502 if (mp_anon != 0) { 503 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, 504 mb_size, (unsigned) mb_mempool_cache, 505 sizeof(struct rte_pktmbuf_pool_private), 506 socket_id, 0); 507 if (rte_mp == NULL) 508 goto err; 509 510 if (rte_mempool_populate_anon(rte_mp) == 0) { 511 rte_mempool_free(rte_mp); 512 rte_mp = NULL; 513 goto err; 514 } 515 rte_pktmbuf_pool_init(rte_mp, NULL); 516 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); 517 } else { 518 /* wrapper to rte_mempool_create() */ 519 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n", 520 rte_mbuf_best_mempool_ops()); 521 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, 522 mb_mempool_cache, 0, mbuf_seg_size, socket_id); 523 } 524 525 err: 526 if (rte_mp == NULL) { 527 rte_exit(EXIT_FAILURE, 528 "Creation of mbuf pool for socket %u failed: %s\n", 529 socket_id, rte_strerror(rte_errno)); 530 } else if (verbose_level > 0) { 531 rte_mempool_dump(stdout, rte_mp); 532 } 533 } 534 535 /* 536 * Check given socket id is valid or not with NUMA mode, 537 * if valid, return 0, else return -1 538 */ 539 static int 540 check_socket_id(const unsigned int socket_id) 541 { 542 static int warning_once = 0; 543 544 if (new_socket_id(socket_id)) { 545 if (!warning_once && numa_support) 546 printf("Warning: NUMA should be configured manually by" 547 " using --port-numa-config and" 548 " --ring-numa-config parameters along with" 549 " --numa.\n"); 550 warning_once = 1; 551 return -1; 552 } 553 return 0; 554 } 555 556 /* 557 * Get the allowed maximum number of RX queues. 558 * *pid return the port id which has minimal value of 559 * max_rx_queues in all ports. 560 */ 561 queueid_t 562 get_allowed_max_nb_rxq(portid_t *pid) 563 { 564 queueid_t allowed_max_rxq = MAX_QUEUE_ID; 565 portid_t pi; 566 struct rte_eth_dev_info dev_info; 567 568 RTE_ETH_FOREACH_DEV(pi) { 569 rte_eth_dev_info_get(pi, &dev_info); 570 if (dev_info.max_rx_queues < allowed_max_rxq) { 571 allowed_max_rxq = dev_info.max_rx_queues; 572 *pid = pi; 573 } 574 } 575 return allowed_max_rxq; 576 } 577 578 /* 579 * Check input rxq is valid or not. 580 * If input rxq is not greater than any of maximum number 581 * of RX queues of all ports, it is valid. 582 * if valid, return 0, else return -1 583 */ 584 int 585 check_nb_rxq(queueid_t rxq) 586 { 587 queueid_t allowed_max_rxq; 588 portid_t pid = 0; 589 590 allowed_max_rxq = get_allowed_max_nb_rxq(&pid); 591 if (rxq > allowed_max_rxq) { 592 printf("Fail: input rxq (%u) can't be greater " 593 "than max_rx_queues (%u) of port %u\n", 594 rxq, 595 allowed_max_rxq, 596 pid); 597 return -1; 598 } 599 return 0; 600 } 601 602 /* 603 * Get the allowed maximum number of TX queues. 604 * *pid return the port id which has minimal value of 605 * max_tx_queues in all ports. 606 */ 607 queueid_t 608 get_allowed_max_nb_txq(portid_t *pid) 609 { 610 queueid_t allowed_max_txq = MAX_QUEUE_ID; 611 portid_t pi; 612 struct rte_eth_dev_info dev_info; 613 614 RTE_ETH_FOREACH_DEV(pi) { 615 rte_eth_dev_info_get(pi, &dev_info); 616 if (dev_info.max_tx_queues < allowed_max_txq) { 617 allowed_max_txq = dev_info.max_tx_queues; 618 *pid = pi; 619 } 620 } 621 return allowed_max_txq; 622 } 623 624 /* 625 * Check input txq is valid or not. 626 * If input txq is not greater than any of maximum number 627 * of TX queues of all ports, it is valid. 628 * if valid, return 0, else return -1 629 */ 630 int 631 check_nb_txq(queueid_t txq) 632 { 633 queueid_t allowed_max_txq; 634 portid_t pid = 0; 635 636 allowed_max_txq = get_allowed_max_nb_txq(&pid); 637 if (txq > allowed_max_txq) { 638 printf("Fail: input txq (%u) can't be greater " 639 "than max_tx_queues (%u) of port %u\n", 640 txq, 641 allowed_max_txq, 642 pid); 643 return -1; 644 } 645 return 0; 646 } 647 648 static void 649 init_config(void) 650 { 651 portid_t pid; 652 struct rte_port *port; 653 struct rte_mempool *mbp; 654 unsigned int nb_mbuf_per_pool; 655 lcoreid_t lc_id; 656 uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; 657 struct rte_gro_param gro_param; 658 uint32_t gso_types; 659 660 memset(port_per_socket,0,RTE_MAX_NUMA_NODES); 661 662 if (numa_support) { 663 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 664 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 665 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 666 } 667 668 /* Configuration of logical cores. */ 669 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 670 sizeof(struct fwd_lcore *) * nb_lcores, 671 RTE_CACHE_LINE_SIZE); 672 if (fwd_lcores == NULL) { 673 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 674 "failed\n", nb_lcores); 675 } 676 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 677 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 678 sizeof(struct fwd_lcore), 679 RTE_CACHE_LINE_SIZE); 680 if (fwd_lcores[lc_id] == NULL) { 681 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 682 "failed\n"); 683 } 684 fwd_lcores[lc_id]->cpuid_idx = lc_id; 685 } 686 687 RTE_ETH_FOREACH_DEV(pid) { 688 port = &ports[pid]; 689 /* Apply default TxRx configuration for all ports */ 690 port->dev_conf.txmode = tx_mode; 691 port->dev_conf.rxmode = rx_mode; 692 rte_eth_dev_info_get(pid, &port->dev_info); 693 if (!(port->dev_info.tx_offload_capa & 694 DEV_TX_OFFLOAD_MBUF_FAST_FREE)) 695 port->dev_conf.txmode.offloads &= 696 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; 697 if (numa_support) { 698 if (port_numa[pid] != NUMA_NO_CONFIG) 699 port_per_socket[port_numa[pid]]++; 700 else { 701 uint32_t socket_id = rte_eth_dev_socket_id(pid); 702 703 /* if socket_id is invalid, set to 0 */ 704 if (check_socket_id(socket_id) < 0) 705 socket_id = 0; 706 port_per_socket[socket_id]++; 707 } 708 } 709 710 /* set flag to initialize port/queue */ 711 port->need_reconfig = 1; 712 port->need_reconfig_queues = 1; 713 } 714 715 /* 716 * Create pools of mbuf. 717 * If NUMA support is disabled, create a single pool of mbuf in 718 * socket 0 memory by default. 719 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 720 * 721 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 722 * nb_txd can be configured at run time. 723 */ 724 if (param_total_num_mbufs) 725 nb_mbuf_per_pool = param_total_num_mbufs; 726 else { 727 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + 728 (nb_lcores * mb_mempool_cache) + 729 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 730 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS; 731 } 732 733 if (numa_support) { 734 uint8_t i; 735 736 for (i = 0; i < num_sockets; i++) 737 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 738 socket_ids[i]); 739 } else { 740 if (socket_num == UMA_NO_CONFIG) 741 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); 742 else 743 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 744 socket_num); 745 } 746 747 init_port_config(); 748 749 gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 750 DEV_TX_OFFLOAD_GRE_TNL_TSO; 751 /* 752 * Records which Mbuf pool to use by each logical core, if needed. 753 */ 754 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 755 mbp = mbuf_pool_find( 756 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 757 758 if (mbp == NULL) 759 mbp = mbuf_pool_find(0); 760 fwd_lcores[lc_id]->mbp = mbp; 761 /* initialize GSO context */ 762 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp; 763 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp; 764 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types; 765 fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN - 766 ETHER_CRC_LEN; 767 fwd_lcores[lc_id]->gso_ctx.flag = 0; 768 } 769 770 /* Configuration of packet forwarding streams. */ 771 if (init_fwd_streams() < 0) 772 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 773 774 fwd_config_setup(); 775 776 /* create a gro context for each lcore */ 777 gro_param.gro_types = RTE_GRO_TCP_IPV4; 778 gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES; 779 gro_param.max_item_per_flow = MAX_PKT_BURST; 780 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 781 gro_param.socket_id = rte_lcore_to_socket_id( 782 fwd_lcores_cpuids[lc_id]); 783 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param); 784 if (fwd_lcores[lc_id]->gro_ctx == NULL) { 785 rte_exit(EXIT_FAILURE, 786 "rte_gro_ctx_create() failed\n"); 787 } 788 } 789 } 790 791 792 void 793 reconfig(portid_t new_port_id, unsigned socket_id) 794 { 795 struct rte_port *port; 796 797 /* Reconfiguration of Ethernet ports. */ 798 port = &ports[new_port_id]; 799 rte_eth_dev_info_get(new_port_id, &port->dev_info); 800 801 /* set flag to initialize port/queue */ 802 port->need_reconfig = 1; 803 port->need_reconfig_queues = 1; 804 port->socket_id = socket_id; 805 806 init_port_config(); 807 } 808 809 810 int 811 init_fwd_streams(void) 812 { 813 portid_t pid; 814 struct rte_port *port; 815 streamid_t sm_id, nb_fwd_streams_new; 816 queueid_t q; 817 818 /* set socket id according to numa or not */ 819 RTE_ETH_FOREACH_DEV(pid) { 820 port = &ports[pid]; 821 if (nb_rxq > port->dev_info.max_rx_queues) { 822 printf("Fail: nb_rxq(%d) is greater than " 823 "max_rx_queues(%d)\n", nb_rxq, 824 port->dev_info.max_rx_queues); 825 return -1; 826 } 827 if (nb_txq > port->dev_info.max_tx_queues) { 828 printf("Fail: nb_txq(%d) is greater than " 829 "max_tx_queues(%d)\n", nb_txq, 830 port->dev_info.max_tx_queues); 831 return -1; 832 } 833 if (numa_support) { 834 if (port_numa[pid] != NUMA_NO_CONFIG) 835 port->socket_id = port_numa[pid]; 836 else { 837 port->socket_id = rte_eth_dev_socket_id(pid); 838 839 /* if socket_id is invalid, set to 0 */ 840 if (check_socket_id(port->socket_id) < 0) 841 port->socket_id = 0; 842 } 843 } 844 else { 845 if (socket_num == UMA_NO_CONFIG) 846 port->socket_id = 0; 847 else 848 port->socket_id = socket_num; 849 } 850 } 851 852 q = RTE_MAX(nb_rxq, nb_txq); 853 if (q == 0) { 854 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n"); 855 return -1; 856 } 857 nb_fwd_streams_new = (streamid_t)(nb_ports * q); 858 if (nb_fwd_streams_new == nb_fwd_streams) 859 return 0; 860 /* clear the old */ 861 if (fwd_streams != NULL) { 862 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 863 if (fwd_streams[sm_id] == NULL) 864 continue; 865 rte_free(fwd_streams[sm_id]); 866 fwd_streams[sm_id] = NULL; 867 } 868 rte_free(fwd_streams); 869 fwd_streams = NULL; 870 } 871 872 /* init new */ 873 nb_fwd_streams = nb_fwd_streams_new; 874 fwd_streams = rte_zmalloc("testpmd: fwd_streams", 875 sizeof(struct fwd_stream *) * nb_fwd_streams, RTE_CACHE_LINE_SIZE); 876 if (fwd_streams == NULL) 877 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " 878 "failed\n", nb_fwd_streams); 879 880 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 881 fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", 882 sizeof(struct fwd_stream), RTE_CACHE_LINE_SIZE); 883 if (fwd_streams[sm_id] == NULL) 884 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" 885 " failed\n"); 886 } 887 888 return 0; 889 } 890 891 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 892 static void 893 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 894 { 895 unsigned int total_burst; 896 unsigned int nb_burst; 897 unsigned int burst_stats[3]; 898 uint16_t pktnb_stats[3]; 899 uint16_t nb_pkt; 900 int burst_percent[3]; 901 902 /* 903 * First compute the total number of packet bursts and the 904 * two highest numbers of bursts of the same number of packets. 905 */ 906 total_burst = 0; 907 burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 908 pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 909 for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 910 nb_burst = pbs->pkt_burst_spread[nb_pkt]; 911 if (nb_burst == 0) 912 continue; 913 total_burst += nb_burst; 914 if (nb_burst > burst_stats[0]) { 915 burst_stats[1] = burst_stats[0]; 916 pktnb_stats[1] = pktnb_stats[0]; 917 burst_stats[0] = nb_burst; 918 pktnb_stats[0] = nb_pkt; 919 } 920 } 921 if (total_burst == 0) 922 return; 923 burst_percent[0] = (burst_stats[0] * 100) / total_burst; 924 printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 925 burst_percent[0], (int) pktnb_stats[0]); 926 if (burst_stats[0] == total_burst) { 927 printf("]\n"); 928 return; 929 } 930 if (burst_stats[0] + burst_stats[1] == total_burst) { 931 printf(" + %d%% of %d pkts]\n", 932 100 - burst_percent[0], pktnb_stats[1]); 933 return; 934 } 935 burst_percent[1] = (burst_stats[1] * 100) / total_burst; 936 burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 937 if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 938 printf(" + %d%% of others]\n", 100 - burst_percent[0]); 939 return; 940 } 941 printf(" + %d%% of %d pkts + %d%% of others]\n", 942 burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 943 } 944 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 945 946 static void 947 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats) 948 { 949 struct rte_port *port; 950 uint8_t i; 951 952 static const char *fwd_stats_border = "----------------------"; 953 954 port = &ports[port_id]; 955 printf("\n %s Forward statistics for port %-2d %s\n", 956 fwd_stats_border, port_id, fwd_stats_border); 957 958 if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) { 959 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 960 "%-"PRIu64"\n", 961 stats->ipackets, stats->imissed, 962 (uint64_t) (stats->ipackets + stats->imissed)); 963 964 if (cur_fwd_eng == &csum_fwd_engine) 965 printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64" \n", 966 port->rx_bad_ip_csum, port->rx_bad_l4_csum); 967 if ((stats->ierrors + stats->rx_nombuf) > 0) { 968 printf(" RX-error: %-"PRIu64"\n", stats->ierrors); 969 printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf); 970 } 971 972 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 973 "%-"PRIu64"\n", 974 stats->opackets, port->tx_dropped, 975 (uint64_t) (stats->opackets + port->tx_dropped)); 976 } 977 else { 978 printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:" 979 "%14"PRIu64"\n", 980 stats->ipackets, stats->imissed, 981 (uint64_t) (stats->ipackets + stats->imissed)); 982 983 if (cur_fwd_eng == &csum_fwd_engine) 984 printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64"\n", 985 port->rx_bad_ip_csum, port->rx_bad_l4_csum); 986 if ((stats->ierrors + stats->rx_nombuf) > 0) { 987 printf(" RX-error:%"PRIu64"\n", stats->ierrors); 988 printf(" RX-nombufs: %14"PRIu64"\n", 989 stats->rx_nombuf); 990 } 991 992 printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:" 993 "%14"PRIu64"\n", 994 stats->opackets, port->tx_dropped, 995 (uint64_t) (stats->opackets + port->tx_dropped)); 996 } 997 998 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 999 if (port->rx_stream) 1000 pkt_burst_stats_display("RX", 1001 &port->rx_stream->rx_burst_stats); 1002 if (port->tx_stream) 1003 pkt_burst_stats_display("TX", 1004 &port->tx_stream->tx_burst_stats); 1005 #endif 1006 1007 if (port->rx_queue_stats_mapping_enabled) { 1008 printf("\n"); 1009 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 1010 printf(" Stats reg %2d RX-packets:%14"PRIu64 1011 " RX-errors:%14"PRIu64 1012 " RX-bytes:%14"PRIu64"\n", 1013 i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]); 1014 } 1015 printf("\n"); 1016 } 1017 if (port->tx_queue_stats_mapping_enabled) { 1018 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) { 1019 printf(" Stats reg %2d TX-packets:%14"PRIu64 1020 " TX-bytes:%14"PRIu64"\n", 1021 i, stats->q_opackets[i], stats->q_obytes[i]); 1022 } 1023 } 1024 1025 printf(" %s--------------------------------%s\n", 1026 fwd_stats_border, fwd_stats_border); 1027 } 1028 1029 static void 1030 fwd_stream_stats_display(streamid_t stream_id) 1031 { 1032 struct fwd_stream *fs; 1033 static const char *fwd_top_stats_border = "-------"; 1034 1035 fs = fwd_streams[stream_id]; 1036 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 1037 (fs->fwd_dropped == 0)) 1038 return; 1039 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 1040 "TX Port=%2d/Queue=%2d %s\n", 1041 fwd_top_stats_border, fs->rx_port, fs->rx_queue, 1042 fs->tx_port, fs->tx_queue, fwd_top_stats_border); 1043 printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u", 1044 fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 1045 1046 /* if checksum mode */ 1047 if (cur_fwd_eng == &csum_fwd_engine) { 1048 printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: " 1049 "%-14u\n", fs->rx_bad_ip_csum, fs->rx_bad_l4_csum); 1050 } 1051 1052 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1053 pkt_burst_stats_display("RX", &fs->rx_burst_stats); 1054 pkt_burst_stats_display("TX", &fs->tx_burst_stats); 1055 #endif 1056 } 1057 1058 static void 1059 flush_fwd_rx_queues(void) 1060 { 1061 struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 1062 portid_t rxp; 1063 portid_t port_id; 1064 queueid_t rxq; 1065 uint16_t nb_rx; 1066 uint16_t i; 1067 uint8_t j; 1068 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 1069 uint64_t timer_period; 1070 1071 /* convert to number of cycles */ 1072 timer_period = rte_get_timer_hz(); /* 1 second timeout */ 1073 1074 for (j = 0; j < 2; j++) { 1075 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 1076 for (rxq = 0; rxq < nb_rxq; rxq++) { 1077 port_id = fwd_ports_ids[rxp]; 1078 /** 1079 * testpmd can stuck in the below do while loop 1080 * if rte_eth_rx_burst() always returns nonzero 1081 * packets. So timer is added to exit this loop 1082 * after 1sec timer expiry. 1083 */ 1084 prev_tsc = rte_rdtsc(); 1085 do { 1086 nb_rx = rte_eth_rx_burst(port_id, rxq, 1087 pkts_burst, MAX_PKT_BURST); 1088 for (i = 0; i < nb_rx; i++) 1089 rte_pktmbuf_free(pkts_burst[i]); 1090 1091 cur_tsc = rte_rdtsc(); 1092 diff_tsc = cur_tsc - prev_tsc; 1093 timer_tsc += diff_tsc; 1094 } while ((nb_rx > 0) && 1095 (timer_tsc < timer_period)); 1096 timer_tsc = 0; 1097 } 1098 } 1099 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 1100 } 1101 } 1102 1103 static void 1104 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 1105 { 1106 struct fwd_stream **fsm; 1107 streamid_t nb_fs; 1108 streamid_t sm_id; 1109 #ifdef RTE_LIBRTE_BITRATE 1110 uint64_t tics_per_1sec; 1111 uint64_t tics_datum; 1112 uint64_t tics_current; 1113 uint8_t idx_port, cnt_ports; 1114 1115 cnt_ports = rte_eth_dev_count(); 1116 tics_datum = rte_rdtsc(); 1117 tics_per_1sec = rte_get_timer_hz(); 1118 #endif 1119 fsm = &fwd_streams[fc->stream_idx]; 1120 nb_fs = fc->stream_nb; 1121 do { 1122 for (sm_id = 0; sm_id < nb_fs; sm_id++) 1123 (*pkt_fwd)(fsm[sm_id]); 1124 #ifdef RTE_LIBRTE_BITRATE 1125 if (bitrate_enabled != 0 && 1126 bitrate_lcore_id == rte_lcore_id()) { 1127 tics_current = rte_rdtsc(); 1128 if (tics_current - tics_datum >= tics_per_1sec) { 1129 /* Periodic bitrate calculation */ 1130 for (idx_port = 0; 1131 idx_port < cnt_ports; 1132 idx_port++) 1133 rte_stats_bitrate_calc(bitrate_data, 1134 idx_port); 1135 tics_datum = tics_current; 1136 } 1137 } 1138 #endif 1139 #ifdef RTE_LIBRTE_LATENCY_STATS 1140 if (latencystats_enabled != 0 && 1141 latencystats_lcore_id == rte_lcore_id()) 1142 rte_latencystats_update(); 1143 #endif 1144 1145 } while (! fc->stopped); 1146 } 1147 1148 static int 1149 start_pkt_forward_on_core(void *fwd_arg) 1150 { 1151 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 1152 cur_fwd_config.fwd_eng->packet_fwd); 1153 return 0; 1154 } 1155 1156 /* 1157 * Run the TXONLY packet forwarding engine to send a single burst of packets. 1158 * Used to start communication flows in network loopback test configurations. 1159 */ 1160 static int 1161 run_one_txonly_burst_on_core(void *fwd_arg) 1162 { 1163 struct fwd_lcore *fwd_lc; 1164 struct fwd_lcore tmp_lcore; 1165 1166 fwd_lc = (struct fwd_lcore *) fwd_arg; 1167 tmp_lcore = *fwd_lc; 1168 tmp_lcore.stopped = 1; 1169 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 1170 return 0; 1171 } 1172 1173 /* 1174 * Launch packet forwarding: 1175 * - Setup per-port forwarding context. 1176 * - launch logical cores with their forwarding configuration. 1177 */ 1178 static void 1179 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 1180 { 1181 port_fwd_begin_t port_fwd_begin; 1182 unsigned int i; 1183 unsigned int lc_id; 1184 int diag; 1185 1186 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 1187 if (port_fwd_begin != NULL) { 1188 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1189 (*port_fwd_begin)(fwd_ports_ids[i]); 1190 } 1191 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 1192 lc_id = fwd_lcores_cpuids[i]; 1193 if ((interactive == 0) || (lc_id != rte_lcore_id())) { 1194 fwd_lcores[i]->stopped = 0; 1195 diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 1196 fwd_lcores[i], lc_id); 1197 if (diag != 0) 1198 printf("launch lcore %u failed - diag=%d\n", 1199 lc_id, diag); 1200 } 1201 } 1202 } 1203 1204 /* 1205 * Launch packet forwarding configuration. 1206 */ 1207 void 1208 start_packet_forwarding(int with_tx_first) 1209 { 1210 port_fwd_begin_t port_fwd_begin; 1211 port_fwd_end_t port_fwd_end; 1212 struct rte_port *port; 1213 unsigned int i; 1214 portid_t pt_id; 1215 streamid_t sm_id; 1216 1217 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) 1218 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); 1219 1220 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq) 1221 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n"); 1222 1223 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 && 1224 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) && 1225 (!nb_rxq || !nb_txq)) 1226 rte_exit(EXIT_FAILURE, 1227 "Either rxq or txq are 0, cannot use %s fwd mode\n", 1228 cur_fwd_eng->fwd_mode_name); 1229 1230 if (all_ports_started() == 0) { 1231 printf("Not all ports were started\n"); 1232 return; 1233 } 1234 if (test_done == 0) { 1235 printf("Packet forwarding already started\n"); 1236 return; 1237 } 1238 1239 if (init_fwd_streams() < 0) { 1240 printf("Fail from init_fwd_streams()\n"); 1241 return; 1242 } 1243 1244 if(dcb_test) { 1245 for (i = 0; i < nb_fwd_ports; i++) { 1246 pt_id = fwd_ports_ids[i]; 1247 port = &ports[pt_id]; 1248 if (!port->dcb_flag) { 1249 printf("In DCB mode, all forwarding ports must " 1250 "be configured in this mode.\n"); 1251 return; 1252 } 1253 } 1254 if (nb_fwd_lcores == 1) { 1255 printf("In DCB mode,the nb forwarding cores " 1256 "should be larger than 1.\n"); 1257 return; 1258 } 1259 } 1260 test_done = 0; 1261 1262 if(!no_flush_rx) 1263 flush_fwd_rx_queues(); 1264 1265 fwd_config_setup(); 1266 pkt_fwd_config_display(&cur_fwd_config); 1267 rxtx_config_display(); 1268 1269 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1270 pt_id = fwd_ports_ids[i]; 1271 port = &ports[pt_id]; 1272 rte_eth_stats_get(pt_id, &port->stats); 1273 port->tx_dropped = 0; 1274 1275 map_port_queue_stats_mapping_registers(pt_id, port); 1276 } 1277 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1278 fwd_streams[sm_id]->rx_packets = 0; 1279 fwd_streams[sm_id]->tx_packets = 0; 1280 fwd_streams[sm_id]->fwd_dropped = 0; 1281 fwd_streams[sm_id]->rx_bad_ip_csum = 0; 1282 fwd_streams[sm_id]->rx_bad_l4_csum = 0; 1283 1284 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1285 memset(&fwd_streams[sm_id]->rx_burst_stats, 0, 1286 sizeof(fwd_streams[sm_id]->rx_burst_stats)); 1287 memset(&fwd_streams[sm_id]->tx_burst_stats, 0, 1288 sizeof(fwd_streams[sm_id]->tx_burst_stats)); 1289 #endif 1290 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1291 fwd_streams[sm_id]->core_cycles = 0; 1292 #endif 1293 } 1294 if (with_tx_first) { 1295 port_fwd_begin = tx_only_engine.port_fwd_begin; 1296 if (port_fwd_begin != NULL) { 1297 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1298 (*port_fwd_begin)(fwd_ports_ids[i]); 1299 } 1300 while (with_tx_first--) { 1301 launch_packet_forwarding( 1302 run_one_txonly_burst_on_core); 1303 rte_eal_mp_wait_lcore(); 1304 } 1305 port_fwd_end = tx_only_engine.port_fwd_end; 1306 if (port_fwd_end != NULL) { 1307 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 1308 (*port_fwd_end)(fwd_ports_ids[i]); 1309 } 1310 } 1311 launch_packet_forwarding(start_pkt_forward_on_core); 1312 } 1313 1314 void 1315 stop_packet_forwarding(void) 1316 { 1317 struct rte_eth_stats stats; 1318 struct rte_port *port; 1319 port_fwd_end_t port_fwd_end; 1320 int i; 1321 portid_t pt_id; 1322 streamid_t sm_id; 1323 lcoreid_t lc_id; 1324 uint64_t total_recv; 1325 uint64_t total_xmit; 1326 uint64_t total_rx_dropped; 1327 uint64_t total_tx_dropped; 1328 uint64_t total_rx_nombuf; 1329 uint64_t tx_dropped; 1330 uint64_t rx_bad_ip_csum; 1331 uint64_t rx_bad_l4_csum; 1332 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1333 uint64_t fwd_cycles; 1334 #endif 1335 1336 static const char *acc_stats_border = "+++++++++++++++"; 1337 1338 if (test_done) { 1339 printf("Packet forwarding not started\n"); 1340 return; 1341 } 1342 printf("Telling cores to stop..."); 1343 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 1344 fwd_lcores[lc_id]->stopped = 1; 1345 printf("\nWaiting for lcores to finish...\n"); 1346 rte_eal_mp_wait_lcore(); 1347 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 1348 if (port_fwd_end != NULL) { 1349 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1350 pt_id = fwd_ports_ids[i]; 1351 (*port_fwd_end)(pt_id); 1352 } 1353 } 1354 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1355 fwd_cycles = 0; 1356 #endif 1357 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1358 if (cur_fwd_config.nb_fwd_streams > 1359 cur_fwd_config.nb_fwd_ports) { 1360 fwd_stream_stats_display(sm_id); 1361 ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL; 1362 ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL; 1363 } else { 1364 ports[fwd_streams[sm_id]->tx_port].tx_stream = 1365 fwd_streams[sm_id]; 1366 ports[fwd_streams[sm_id]->rx_port].rx_stream = 1367 fwd_streams[sm_id]; 1368 } 1369 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped; 1370 tx_dropped = (uint64_t) (tx_dropped + 1371 fwd_streams[sm_id]->fwd_dropped); 1372 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped; 1373 1374 rx_bad_ip_csum = 1375 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum; 1376 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum + 1377 fwd_streams[sm_id]->rx_bad_ip_csum); 1378 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum = 1379 rx_bad_ip_csum; 1380 1381 rx_bad_l4_csum = 1382 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum; 1383 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum + 1384 fwd_streams[sm_id]->rx_bad_l4_csum); 1385 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum = 1386 rx_bad_l4_csum; 1387 1388 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1389 fwd_cycles = (uint64_t) (fwd_cycles + 1390 fwd_streams[sm_id]->core_cycles); 1391 #endif 1392 } 1393 total_recv = 0; 1394 total_xmit = 0; 1395 total_rx_dropped = 0; 1396 total_tx_dropped = 0; 1397 total_rx_nombuf = 0; 1398 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1399 pt_id = fwd_ports_ids[i]; 1400 1401 port = &ports[pt_id]; 1402 rte_eth_stats_get(pt_id, &stats); 1403 stats.ipackets -= port->stats.ipackets; 1404 port->stats.ipackets = 0; 1405 stats.opackets -= port->stats.opackets; 1406 port->stats.opackets = 0; 1407 stats.ibytes -= port->stats.ibytes; 1408 port->stats.ibytes = 0; 1409 stats.obytes -= port->stats.obytes; 1410 port->stats.obytes = 0; 1411 stats.imissed -= port->stats.imissed; 1412 port->stats.imissed = 0; 1413 stats.oerrors -= port->stats.oerrors; 1414 port->stats.oerrors = 0; 1415 stats.rx_nombuf -= port->stats.rx_nombuf; 1416 port->stats.rx_nombuf = 0; 1417 1418 total_recv += stats.ipackets; 1419 total_xmit += stats.opackets; 1420 total_rx_dropped += stats.imissed; 1421 total_tx_dropped += port->tx_dropped; 1422 total_rx_nombuf += stats.rx_nombuf; 1423 1424 fwd_port_stats_display(pt_id, &stats); 1425 } 1426 1427 printf("\n %s Accumulated forward statistics for all ports" 1428 "%s\n", 1429 acc_stats_border, acc_stats_border); 1430 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1431 "%-"PRIu64"\n" 1432 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1433 "%-"PRIu64"\n", 1434 total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1435 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1436 if (total_rx_nombuf > 0) 1437 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1438 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1439 "%s\n", 1440 acc_stats_border, acc_stats_border); 1441 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1442 if (total_recv > 0) 1443 printf("\n CPU cycles/packet=%u (total cycles=" 1444 "%"PRIu64" / total RX packets=%"PRIu64")\n", 1445 (unsigned int)(fwd_cycles / total_recv), 1446 fwd_cycles, total_recv); 1447 #endif 1448 printf("\nDone.\n"); 1449 test_done = 1; 1450 } 1451 1452 void 1453 dev_set_link_up(portid_t pid) 1454 { 1455 if (rte_eth_dev_set_link_up(pid) < 0) 1456 printf("\nSet link up fail.\n"); 1457 } 1458 1459 void 1460 dev_set_link_down(portid_t pid) 1461 { 1462 if (rte_eth_dev_set_link_down(pid) < 0) 1463 printf("\nSet link down fail.\n"); 1464 } 1465 1466 static int 1467 all_ports_started(void) 1468 { 1469 portid_t pi; 1470 struct rte_port *port; 1471 1472 RTE_ETH_FOREACH_DEV(pi) { 1473 port = &ports[pi]; 1474 /* Check if there is a port which is not started */ 1475 if ((port->port_status != RTE_PORT_STARTED) && 1476 (port->slave_flag == 0)) 1477 return 0; 1478 } 1479 1480 /* No port is not started */ 1481 return 1; 1482 } 1483 1484 int 1485 port_is_stopped(portid_t port_id) 1486 { 1487 struct rte_port *port = &ports[port_id]; 1488 1489 if ((port->port_status != RTE_PORT_STOPPED) && 1490 (port->slave_flag == 0)) 1491 return 0; 1492 return 1; 1493 } 1494 1495 int 1496 all_ports_stopped(void) 1497 { 1498 portid_t pi; 1499 1500 RTE_ETH_FOREACH_DEV(pi) { 1501 if (!port_is_stopped(pi)) 1502 return 0; 1503 } 1504 1505 return 1; 1506 } 1507 1508 int 1509 port_is_started(portid_t port_id) 1510 { 1511 if (port_id_is_invalid(port_id, ENABLED_WARN)) 1512 return 0; 1513 1514 if (ports[port_id].port_status != RTE_PORT_STARTED) 1515 return 0; 1516 1517 return 1; 1518 } 1519 1520 static int 1521 port_is_closed(portid_t port_id) 1522 { 1523 if (port_id_is_invalid(port_id, ENABLED_WARN)) 1524 return 0; 1525 1526 if (ports[port_id].port_status != RTE_PORT_CLOSED) 1527 return 0; 1528 1529 return 1; 1530 } 1531 1532 int 1533 start_port(portid_t pid) 1534 { 1535 int diag, need_check_link_status = -1; 1536 portid_t pi; 1537 queueid_t qi; 1538 struct rte_port *port; 1539 struct ether_addr mac_addr; 1540 enum rte_eth_event_type event_type; 1541 1542 if (port_id_is_invalid(pid, ENABLED_WARN)) 1543 return 0; 1544 1545 if(dcb_config) 1546 dcb_test = 1; 1547 RTE_ETH_FOREACH_DEV(pi) { 1548 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1549 continue; 1550 1551 need_check_link_status = 0; 1552 port = &ports[pi]; 1553 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 1554 RTE_PORT_HANDLING) == 0) { 1555 printf("Port %d is now not stopped\n", pi); 1556 continue; 1557 } 1558 1559 if (port->need_reconfig > 0) { 1560 port->need_reconfig = 0; 1561 1562 if (flow_isolate_all) { 1563 int ret = port_flow_isolate(pi, 1); 1564 if (ret) { 1565 printf("Failed to apply isolated" 1566 " mode on port %d\n", pi); 1567 return -1; 1568 } 1569 } 1570 1571 printf("Configuring Port %d (socket %u)\n", pi, 1572 port->socket_id); 1573 /* configure port */ 1574 diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, 1575 &(port->dev_conf)); 1576 if (diag != 0) { 1577 if (rte_atomic16_cmpset(&(port->port_status), 1578 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1579 printf("Port %d can not be set back " 1580 "to stopped\n", pi); 1581 printf("Fail to configure port %d\n", pi); 1582 /* try to reconfigure port next time */ 1583 port->need_reconfig = 1; 1584 return -1; 1585 } 1586 } 1587 if (port->need_reconfig_queues > 0) { 1588 port->need_reconfig_queues = 0; 1589 port->tx_conf.txq_flags = ETH_TXQ_FLAGS_IGNORE; 1590 /* Apply Tx offloads configuration */ 1591 port->tx_conf.offloads = port->dev_conf.txmode.offloads; 1592 /* setup tx queues */ 1593 for (qi = 0; qi < nb_txq; qi++) { 1594 if ((numa_support) && 1595 (txring_numa[pi] != NUMA_NO_CONFIG)) 1596 diag = rte_eth_tx_queue_setup(pi, qi, 1597 nb_txd,txring_numa[pi], 1598 &(port->tx_conf)); 1599 else 1600 diag = rte_eth_tx_queue_setup(pi, qi, 1601 nb_txd,port->socket_id, 1602 &(port->tx_conf)); 1603 1604 if (diag == 0) 1605 continue; 1606 1607 /* Fail to setup tx queue, return */ 1608 if (rte_atomic16_cmpset(&(port->port_status), 1609 RTE_PORT_HANDLING, 1610 RTE_PORT_STOPPED) == 0) 1611 printf("Port %d can not be set back " 1612 "to stopped\n", pi); 1613 printf("Fail to configure port %d tx queues\n", pi); 1614 /* try to reconfigure queues next time */ 1615 port->need_reconfig_queues = 1; 1616 return -1; 1617 } 1618 /* Apply Rx offloads configuration */ 1619 port->rx_conf.offloads = port->dev_conf.rxmode.offloads; 1620 /* setup rx queues */ 1621 for (qi = 0; qi < nb_rxq; qi++) { 1622 if ((numa_support) && 1623 (rxring_numa[pi] != NUMA_NO_CONFIG)) { 1624 struct rte_mempool * mp = 1625 mbuf_pool_find(rxring_numa[pi]); 1626 if (mp == NULL) { 1627 printf("Failed to setup RX queue:" 1628 "No mempool allocation" 1629 " on the socket %d\n", 1630 rxring_numa[pi]); 1631 return -1; 1632 } 1633 1634 diag = rte_eth_rx_queue_setup(pi, qi, 1635 nb_rxd,rxring_numa[pi], 1636 &(port->rx_conf),mp); 1637 } else { 1638 struct rte_mempool *mp = 1639 mbuf_pool_find(port->socket_id); 1640 if (mp == NULL) { 1641 printf("Failed to setup RX queue:" 1642 "No mempool allocation" 1643 " on the socket %d\n", 1644 port->socket_id); 1645 return -1; 1646 } 1647 diag = rte_eth_rx_queue_setup(pi, qi, 1648 nb_rxd,port->socket_id, 1649 &(port->rx_conf), mp); 1650 } 1651 if (diag == 0) 1652 continue; 1653 1654 /* Fail to setup rx queue, return */ 1655 if (rte_atomic16_cmpset(&(port->port_status), 1656 RTE_PORT_HANDLING, 1657 RTE_PORT_STOPPED) == 0) 1658 printf("Port %d can not be set back " 1659 "to stopped\n", pi); 1660 printf("Fail to configure port %d rx queues\n", pi); 1661 /* try to reconfigure queues next time */ 1662 port->need_reconfig_queues = 1; 1663 return -1; 1664 } 1665 } 1666 1667 /* start port */ 1668 if (rte_eth_dev_start(pi) < 0) { 1669 printf("Fail to start port %d\n", pi); 1670 1671 /* Fail to setup rx queue, return */ 1672 if (rte_atomic16_cmpset(&(port->port_status), 1673 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1674 printf("Port %d can not be set back to " 1675 "stopped\n", pi); 1676 continue; 1677 } 1678 1679 if (rte_atomic16_cmpset(&(port->port_status), 1680 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 1681 printf("Port %d can not be set into started\n", pi); 1682 1683 rte_eth_macaddr_get(pi, &mac_addr); 1684 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 1685 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 1686 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 1687 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 1688 1689 /* at least one port started, need checking link status */ 1690 need_check_link_status = 1; 1691 } 1692 1693 for (event_type = RTE_ETH_EVENT_UNKNOWN; 1694 event_type < RTE_ETH_EVENT_MAX; 1695 event_type++) { 1696 diag = rte_eth_dev_callback_register(RTE_ETH_ALL, 1697 event_type, 1698 eth_event_callback, 1699 NULL); 1700 if (diag) { 1701 printf("Failed to setup even callback for event %d\n", 1702 event_type); 1703 return -1; 1704 } 1705 } 1706 1707 if (need_check_link_status == 1 && !no_link_check) 1708 check_all_ports_link_status(RTE_PORT_ALL); 1709 else if (need_check_link_status == 0) 1710 printf("Please stop the ports first\n"); 1711 1712 printf("Done\n"); 1713 return 0; 1714 } 1715 1716 void 1717 stop_port(portid_t pid) 1718 { 1719 portid_t pi; 1720 struct rte_port *port; 1721 int need_check_link_status = 0; 1722 1723 if (dcb_test) { 1724 dcb_test = 0; 1725 dcb_config = 0; 1726 } 1727 1728 if (port_id_is_invalid(pid, ENABLED_WARN)) 1729 return; 1730 1731 printf("Stopping ports...\n"); 1732 1733 RTE_ETH_FOREACH_DEV(pi) { 1734 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1735 continue; 1736 1737 if (port_is_forwarding(pi) != 0 && test_done == 0) { 1738 printf("Please remove port %d from forwarding configuration.\n", pi); 1739 continue; 1740 } 1741 1742 if (port_is_bonding_slave(pi)) { 1743 printf("Please remove port %d from bonded device.\n", pi); 1744 continue; 1745 } 1746 1747 port = &ports[pi]; 1748 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 1749 RTE_PORT_HANDLING) == 0) 1750 continue; 1751 1752 rte_eth_dev_stop(pi); 1753 1754 if (rte_atomic16_cmpset(&(port->port_status), 1755 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 1756 printf("Port %d can not be set into stopped\n", pi); 1757 need_check_link_status = 1; 1758 } 1759 if (need_check_link_status && !no_link_check) 1760 check_all_ports_link_status(RTE_PORT_ALL); 1761 1762 printf("Done\n"); 1763 } 1764 1765 void 1766 close_port(portid_t pid) 1767 { 1768 portid_t pi; 1769 struct rte_port *port; 1770 1771 if (port_id_is_invalid(pid, ENABLED_WARN)) 1772 return; 1773 1774 printf("Closing ports...\n"); 1775 1776 RTE_ETH_FOREACH_DEV(pi) { 1777 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1778 continue; 1779 1780 if (port_is_forwarding(pi) != 0 && test_done == 0) { 1781 printf("Please remove port %d from forwarding configuration.\n", pi); 1782 continue; 1783 } 1784 1785 if (port_is_bonding_slave(pi)) { 1786 printf("Please remove port %d from bonded device.\n", pi); 1787 continue; 1788 } 1789 1790 port = &ports[pi]; 1791 if (rte_atomic16_cmpset(&(port->port_status), 1792 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { 1793 printf("Port %d is already closed\n", pi); 1794 continue; 1795 } 1796 1797 if (rte_atomic16_cmpset(&(port->port_status), 1798 RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 1799 printf("Port %d is now not stopped\n", pi); 1800 continue; 1801 } 1802 1803 if (port->flow_list) 1804 port_flow_flush(pi); 1805 rte_eth_dev_close(pi); 1806 1807 if (rte_atomic16_cmpset(&(port->port_status), 1808 RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 1809 printf("Port %d cannot be set to closed\n", pi); 1810 } 1811 1812 printf("Done\n"); 1813 } 1814 1815 void 1816 reset_port(portid_t pid) 1817 { 1818 int diag; 1819 portid_t pi; 1820 struct rte_port *port; 1821 1822 if (port_id_is_invalid(pid, ENABLED_WARN)) 1823 return; 1824 1825 printf("Resetting ports...\n"); 1826 1827 RTE_ETH_FOREACH_DEV(pi) { 1828 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 1829 continue; 1830 1831 if (port_is_forwarding(pi) != 0 && test_done == 0) { 1832 printf("Please remove port %d from forwarding " 1833 "configuration.\n", pi); 1834 continue; 1835 } 1836 1837 if (port_is_bonding_slave(pi)) { 1838 printf("Please remove port %d from bonded device.\n", 1839 pi); 1840 continue; 1841 } 1842 1843 diag = rte_eth_dev_reset(pi); 1844 if (diag == 0) { 1845 port = &ports[pi]; 1846 port->need_reconfig = 1; 1847 port->need_reconfig_queues = 1; 1848 } else { 1849 printf("Failed to reset port %d. diag=%d\n", pi, diag); 1850 } 1851 } 1852 1853 printf("Done\n"); 1854 } 1855 1856 void 1857 attach_port(char *identifier) 1858 { 1859 portid_t pi = 0; 1860 unsigned int socket_id; 1861 1862 printf("Attaching a new port...\n"); 1863 1864 if (identifier == NULL) { 1865 printf("Invalid parameters are specified\n"); 1866 return; 1867 } 1868 1869 if (rte_eth_dev_attach(identifier, &pi)) 1870 return; 1871 1872 socket_id = (unsigned)rte_eth_dev_socket_id(pi); 1873 /* if socket_id is invalid, set to 0 */ 1874 if (check_socket_id(socket_id) < 0) 1875 socket_id = 0; 1876 reconfig(pi, socket_id); 1877 rte_eth_promiscuous_enable(pi); 1878 1879 nb_ports = rte_eth_dev_count(); 1880 1881 ports[pi].port_status = RTE_PORT_STOPPED; 1882 1883 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); 1884 printf("Done\n"); 1885 } 1886 1887 void 1888 detach_port(portid_t port_id) 1889 { 1890 char name[RTE_ETH_NAME_MAX_LEN]; 1891 1892 printf("Detaching a port...\n"); 1893 1894 if (!port_is_closed(port_id)) { 1895 printf("Please close port first\n"); 1896 return; 1897 } 1898 1899 if (ports[port_id].flow_list) 1900 port_flow_flush(port_id); 1901 1902 if (rte_eth_dev_detach(port_id, name)) { 1903 TESTPMD_LOG(ERR, "Failed to detach port '%s'\n", name); 1904 return; 1905 } 1906 1907 nb_ports = rte_eth_dev_count(); 1908 1909 printf("Port '%s' is detached. Now total ports is %d\n", 1910 name, nb_ports); 1911 printf("Done\n"); 1912 return; 1913 } 1914 1915 void 1916 pmd_test_exit(void) 1917 { 1918 portid_t pt_id; 1919 1920 if (test_done == 0) 1921 stop_packet_forwarding(); 1922 1923 if (ports != NULL) { 1924 no_link_check = 1; 1925 RTE_ETH_FOREACH_DEV(pt_id) { 1926 printf("\nShutting down port %d...\n", pt_id); 1927 fflush(stdout); 1928 stop_port(pt_id); 1929 close_port(pt_id); 1930 } 1931 } 1932 printf("\nBye...\n"); 1933 } 1934 1935 typedef void (*cmd_func_t)(void); 1936 struct pmd_test_command { 1937 const char *cmd_name; 1938 cmd_func_t cmd_func; 1939 }; 1940 1941 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) 1942 1943 /* Check the link status of all ports in up to 9s, and print them finally */ 1944 static void 1945 check_all_ports_link_status(uint32_t port_mask) 1946 { 1947 #define CHECK_INTERVAL 100 /* 100ms */ 1948 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1949 portid_t portid; 1950 uint8_t count, all_ports_up, print_flag = 0; 1951 struct rte_eth_link link; 1952 1953 printf("Checking link statuses...\n"); 1954 fflush(stdout); 1955 for (count = 0; count <= MAX_CHECK_TIME; count++) { 1956 all_ports_up = 1; 1957 RTE_ETH_FOREACH_DEV(portid) { 1958 if ((port_mask & (1 << portid)) == 0) 1959 continue; 1960 memset(&link, 0, sizeof(link)); 1961 rte_eth_link_get_nowait(portid, &link); 1962 /* print link status if flag set */ 1963 if (print_flag == 1) { 1964 if (link.link_status) 1965 printf( 1966 "Port%d Link Up. speed %u Mbps- %s\n", 1967 portid, link.link_speed, 1968 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 1969 ("full-duplex") : ("half-duplex\n")); 1970 else 1971 printf("Port %d Link Down\n", portid); 1972 continue; 1973 } 1974 /* clear all_ports_up flag if any link down */ 1975 if (link.link_status == ETH_LINK_DOWN) { 1976 all_ports_up = 0; 1977 break; 1978 } 1979 } 1980 /* after finally printing all link status, get out */ 1981 if (print_flag == 1) 1982 break; 1983 1984 if (all_ports_up == 0) { 1985 fflush(stdout); 1986 rte_delay_ms(CHECK_INTERVAL); 1987 } 1988 1989 /* set the print_flag if all ports up or timeout */ 1990 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1991 print_flag = 1; 1992 } 1993 1994 if (lsc_interrupt) 1995 break; 1996 } 1997 } 1998 1999 static void 2000 rmv_event_callback(void *arg) 2001 { 2002 struct rte_eth_dev *dev; 2003 portid_t port_id = (intptr_t)arg; 2004 2005 RTE_ETH_VALID_PORTID_OR_RET(port_id); 2006 dev = &rte_eth_devices[port_id]; 2007 2008 stop_port(port_id); 2009 close_port(port_id); 2010 printf("removing device %s\n", dev->device->name); 2011 if (rte_eal_dev_detach(dev->device)) 2012 TESTPMD_LOG(ERR, "Failed to detach device %s\n", 2013 dev->device->name); 2014 } 2015 2016 /* This function is used by the interrupt thread */ 2017 static int 2018 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param, 2019 void *ret_param) 2020 { 2021 static const char * const event_desc[] = { 2022 [RTE_ETH_EVENT_UNKNOWN] = "Unknown", 2023 [RTE_ETH_EVENT_INTR_LSC] = "LSC", 2024 [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state", 2025 [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset", 2026 [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox", 2027 [RTE_ETH_EVENT_MACSEC] = "MACsec", 2028 [RTE_ETH_EVENT_INTR_RMV] = "device removal", 2029 [RTE_ETH_EVENT_NEW] = "device probed", 2030 [RTE_ETH_EVENT_DESTROY] = "device released", 2031 [RTE_ETH_EVENT_MAX] = NULL, 2032 }; 2033 2034 RTE_SET_USED(param); 2035 RTE_SET_USED(ret_param); 2036 2037 if (type >= RTE_ETH_EVENT_MAX) { 2038 fprintf(stderr, "\nPort %" PRIu8 ": %s called upon invalid event %d\n", 2039 port_id, __func__, type); 2040 fflush(stderr); 2041 } else if (event_print_mask & (UINT32_C(1) << type)) { 2042 printf("\nPort %" PRIu8 ": %s event\n", port_id, 2043 event_desc[type]); 2044 fflush(stdout); 2045 } 2046 2047 if (port_id_is_invalid(port_id, DISABLED_WARN)) 2048 return 0; 2049 2050 switch (type) { 2051 case RTE_ETH_EVENT_INTR_RMV: 2052 if (rte_eal_alarm_set(100000, 2053 rmv_event_callback, (void *)(intptr_t)port_id)) 2054 fprintf(stderr, "Could not set up deferred device removal\n"); 2055 break; 2056 default: 2057 break; 2058 } 2059 return 0; 2060 } 2061 2062 static int 2063 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 2064 { 2065 uint16_t i; 2066 int diag; 2067 uint8_t mapping_found = 0; 2068 2069 for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 2070 if ((tx_queue_stats_mappings[i].port_id == port_id) && 2071 (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 2072 diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 2073 tx_queue_stats_mappings[i].queue_id, 2074 tx_queue_stats_mappings[i].stats_counter_id); 2075 if (diag != 0) 2076 return diag; 2077 mapping_found = 1; 2078 } 2079 } 2080 if (mapping_found) 2081 port->tx_queue_stats_mapping_enabled = 1; 2082 return 0; 2083 } 2084 2085 static int 2086 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 2087 { 2088 uint16_t i; 2089 int diag; 2090 uint8_t mapping_found = 0; 2091 2092 for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 2093 if ((rx_queue_stats_mappings[i].port_id == port_id) && 2094 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 2095 diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 2096 rx_queue_stats_mappings[i].queue_id, 2097 rx_queue_stats_mappings[i].stats_counter_id); 2098 if (diag != 0) 2099 return diag; 2100 mapping_found = 1; 2101 } 2102 } 2103 if (mapping_found) 2104 port->rx_queue_stats_mapping_enabled = 1; 2105 return 0; 2106 } 2107 2108 static void 2109 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port) 2110 { 2111 int diag = 0; 2112 2113 diag = set_tx_queue_stats_mapping_registers(pi, port); 2114 if (diag != 0) { 2115 if (diag == -ENOTSUP) { 2116 port->tx_queue_stats_mapping_enabled = 0; 2117 printf("TX queue stats mapping not supported port id=%d\n", pi); 2118 } 2119 else 2120 rte_exit(EXIT_FAILURE, 2121 "set_tx_queue_stats_mapping_registers " 2122 "failed for port id=%d diag=%d\n", 2123 pi, diag); 2124 } 2125 2126 diag = set_rx_queue_stats_mapping_registers(pi, port); 2127 if (diag != 0) { 2128 if (diag == -ENOTSUP) { 2129 port->rx_queue_stats_mapping_enabled = 0; 2130 printf("RX queue stats mapping not supported port id=%d\n", pi); 2131 } 2132 else 2133 rte_exit(EXIT_FAILURE, 2134 "set_rx_queue_stats_mapping_registers " 2135 "failed for port id=%d diag=%d\n", 2136 pi, diag); 2137 } 2138 } 2139 2140 static void 2141 rxtx_port_config(struct rte_port *port) 2142 { 2143 port->rx_conf = port->dev_info.default_rxconf; 2144 port->tx_conf = port->dev_info.default_txconf; 2145 2146 /* Check if any RX/TX parameters have been passed */ 2147 if (rx_pthresh != RTE_PMD_PARAM_UNSET) 2148 port->rx_conf.rx_thresh.pthresh = rx_pthresh; 2149 2150 if (rx_hthresh != RTE_PMD_PARAM_UNSET) 2151 port->rx_conf.rx_thresh.hthresh = rx_hthresh; 2152 2153 if (rx_wthresh != RTE_PMD_PARAM_UNSET) 2154 port->rx_conf.rx_thresh.wthresh = rx_wthresh; 2155 2156 if (rx_free_thresh != RTE_PMD_PARAM_UNSET) 2157 port->rx_conf.rx_free_thresh = rx_free_thresh; 2158 2159 if (rx_drop_en != RTE_PMD_PARAM_UNSET) 2160 port->rx_conf.rx_drop_en = rx_drop_en; 2161 2162 if (tx_pthresh != RTE_PMD_PARAM_UNSET) 2163 port->tx_conf.tx_thresh.pthresh = tx_pthresh; 2164 2165 if (tx_hthresh != RTE_PMD_PARAM_UNSET) 2166 port->tx_conf.tx_thresh.hthresh = tx_hthresh; 2167 2168 if (tx_wthresh != RTE_PMD_PARAM_UNSET) 2169 port->tx_conf.tx_thresh.wthresh = tx_wthresh; 2170 2171 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET) 2172 port->tx_conf.tx_rs_thresh = tx_rs_thresh; 2173 2174 if (tx_free_thresh != RTE_PMD_PARAM_UNSET) 2175 port->tx_conf.tx_free_thresh = tx_free_thresh; 2176 } 2177 2178 void 2179 init_port_config(void) 2180 { 2181 portid_t pid; 2182 struct rte_port *port; 2183 2184 RTE_ETH_FOREACH_DEV(pid) { 2185 port = &ports[pid]; 2186 port->dev_conf.fdir_conf = fdir_conf; 2187 if (nb_rxq > 1) { 2188 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 2189 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf; 2190 } else { 2191 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 2192 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 2193 } 2194 2195 if (port->dcb_flag == 0) { 2196 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 2197 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 2198 else 2199 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 2200 } 2201 2202 rxtx_port_config(port); 2203 2204 rte_eth_macaddr_get(pid, &port->eth_addr); 2205 2206 map_port_queue_stats_mapping_registers(pid, port); 2207 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS 2208 rte_pmd_ixgbe_bypass_init(pid); 2209 #endif 2210 2211 if (lsc_interrupt && 2212 (rte_eth_devices[pid].data->dev_flags & 2213 RTE_ETH_DEV_INTR_LSC)) 2214 port->dev_conf.intr_conf.lsc = 1; 2215 if (rmv_interrupt && 2216 (rte_eth_devices[pid].data->dev_flags & 2217 RTE_ETH_DEV_INTR_RMV)) 2218 port->dev_conf.intr_conf.rmv = 1; 2219 2220 #if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED 2221 /* Detect softnic port */ 2222 if (!strcmp(port->dev_info.driver_name, "net_softnic")) { 2223 port->softnic_enable = 1; 2224 memset(&port->softport, 0, sizeof(struct softnic_port)); 2225 2226 if (!strcmp(cur_fwd_eng->fwd_mode_name, "tm")) 2227 port->softport.tm_flag = 1; 2228 } 2229 #endif 2230 } 2231 } 2232 2233 void set_port_slave_flag(portid_t slave_pid) 2234 { 2235 struct rte_port *port; 2236 2237 port = &ports[slave_pid]; 2238 port->slave_flag = 1; 2239 } 2240 2241 void clear_port_slave_flag(portid_t slave_pid) 2242 { 2243 struct rte_port *port; 2244 2245 port = &ports[slave_pid]; 2246 port->slave_flag = 0; 2247 } 2248 2249 uint8_t port_is_bonding_slave(portid_t slave_pid) 2250 { 2251 struct rte_port *port; 2252 2253 port = &ports[slave_pid]; 2254 return port->slave_flag; 2255 } 2256 2257 const uint16_t vlan_tags[] = { 2258 0, 1, 2, 3, 4, 5, 6, 7, 2259 8, 9, 10, 11, 12, 13, 14, 15, 2260 16, 17, 18, 19, 20, 21, 22, 23, 2261 24, 25, 26, 27, 28, 29, 30, 31 2262 }; 2263 2264 static int 2265 get_eth_dcb_conf(struct rte_eth_conf *eth_conf, 2266 enum dcb_mode_enable dcb_mode, 2267 enum rte_eth_nb_tcs num_tcs, 2268 uint8_t pfc_en) 2269 { 2270 uint8_t i; 2271 2272 /* 2273 * Builds up the correct configuration for dcb+vt based on the vlan tags array 2274 * given above, and the number of traffic classes available for use. 2275 */ 2276 if (dcb_mode == DCB_VT_ENABLED) { 2277 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf = 2278 ð_conf->rx_adv_conf.vmdq_dcb_conf; 2279 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf = 2280 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf; 2281 2282 /* VMDQ+DCB RX and TX configurations */ 2283 vmdq_rx_conf->enable_default_pool = 0; 2284 vmdq_rx_conf->default_pool = 0; 2285 vmdq_rx_conf->nb_queue_pools = 2286 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 2287 vmdq_tx_conf->nb_queue_pools = 2288 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 2289 2290 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools; 2291 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) { 2292 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i]; 2293 vmdq_rx_conf->pool_map[i].pools = 2294 1 << (i % vmdq_rx_conf->nb_queue_pools); 2295 } 2296 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 2297 vmdq_rx_conf->dcb_tc[i] = i % num_tcs; 2298 vmdq_tx_conf->dcb_tc[i] = i % num_tcs; 2299 } 2300 2301 /* set DCB mode of RX and TX of multiple queues */ 2302 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 2303 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 2304 } else { 2305 struct rte_eth_dcb_rx_conf *rx_conf = 2306 ð_conf->rx_adv_conf.dcb_rx_conf; 2307 struct rte_eth_dcb_tx_conf *tx_conf = 2308 ð_conf->tx_adv_conf.dcb_tx_conf; 2309 2310 rx_conf->nb_tcs = num_tcs; 2311 tx_conf->nb_tcs = num_tcs; 2312 2313 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 2314 rx_conf->dcb_tc[i] = i % num_tcs; 2315 tx_conf->dcb_tc[i] = i % num_tcs; 2316 } 2317 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; 2318 eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf; 2319 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 2320 } 2321 2322 if (pfc_en) 2323 eth_conf->dcb_capability_en = 2324 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT; 2325 else 2326 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 2327 2328 return 0; 2329 } 2330 2331 int 2332 init_port_dcb_config(portid_t pid, 2333 enum dcb_mode_enable dcb_mode, 2334 enum rte_eth_nb_tcs num_tcs, 2335 uint8_t pfc_en) 2336 { 2337 struct rte_eth_conf port_conf; 2338 struct rte_port *rte_port; 2339 int retval; 2340 uint16_t i; 2341 2342 rte_port = &ports[pid]; 2343 2344 memset(&port_conf, 0, sizeof(struct rte_eth_conf)); 2345 /* Enter DCB configuration status */ 2346 dcb_config = 1; 2347 2348 port_conf.rxmode = rte_port->dev_conf.rxmode; 2349 port_conf.txmode = rte_port->dev_conf.txmode; 2350 2351 /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 2352 retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); 2353 if (retval < 0) 2354 return retval; 2355 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 2356 2357 /** 2358 * Write the configuration into the device. 2359 * Set the numbers of RX & TX queues to 0, so 2360 * the RX & TX queues will not be setup. 2361 */ 2362 rte_eth_dev_configure(pid, 0, 0, &port_conf); 2363 2364 rte_eth_dev_info_get(pid, &rte_port->dev_info); 2365 2366 /* If dev_info.vmdq_pool_base is greater than 0, 2367 * the queue id of vmdq pools is started after pf queues. 2368 */ 2369 if (dcb_mode == DCB_VT_ENABLED && 2370 rte_port->dev_info.vmdq_pool_base > 0) { 2371 printf("VMDQ_DCB multi-queue mode is nonsensical" 2372 " for port %d.", pid); 2373 return -1; 2374 } 2375 2376 /* Assume the ports in testpmd have the same dcb capability 2377 * and has the same number of rxq and txq in dcb mode 2378 */ 2379 if (dcb_mode == DCB_VT_ENABLED) { 2380 if (rte_port->dev_info.max_vfs > 0) { 2381 nb_rxq = rte_port->dev_info.nb_rx_queues; 2382 nb_txq = rte_port->dev_info.nb_tx_queues; 2383 } else { 2384 nb_rxq = rte_port->dev_info.max_rx_queues; 2385 nb_txq = rte_port->dev_info.max_tx_queues; 2386 } 2387 } else { 2388 /*if vt is disabled, use all pf queues */ 2389 if (rte_port->dev_info.vmdq_pool_base == 0) { 2390 nb_rxq = rte_port->dev_info.max_rx_queues; 2391 nb_txq = rte_port->dev_info.max_tx_queues; 2392 } else { 2393 nb_rxq = (queueid_t)num_tcs; 2394 nb_txq = (queueid_t)num_tcs; 2395 2396 } 2397 } 2398 rx_free_thresh = 64; 2399 2400 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); 2401 2402 rxtx_port_config(rte_port); 2403 /* VLAN filter */ 2404 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 2405 for (i = 0; i < RTE_DIM(vlan_tags); i++) 2406 rx_vft_set(pid, vlan_tags[i], 1); 2407 2408 rte_eth_macaddr_get(pid, &rte_port->eth_addr); 2409 map_port_queue_stats_mapping_registers(pid, rte_port); 2410 2411 rte_port->dcb_flag = 1; 2412 2413 return 0; 2414 } 2415 2416 static void 2417 init_port(void) 2418 { 2419 /* Configuration of Ethernet ports. */ 2420 ports = rte_zmalloc("testpmd: ports", 2421 sizeof(struct rte_port) * RTE_MAX_ETHPORTS, 2422 RTE_CACHE_LINE_SIZE); 2423 if (ports == NULL) { 2424 rte_exit(EXIT_FAILURE, 2425 "rte_zmalloc(%d struct rte_port) failed\n", 2426 RTE_MAX_ETHPORTS); 2427 } 2428 } 2429 2430 static void 2431 force_quit(void) 2432 { 2433 pmd_test_exit(); 2434 prompt_exit(); 2435 } 2436 2437 static void 2438 print_stats(void) 2439 { 2440 uint8_t i; 2441 const char clr[] = { 27, '[', '2', 'J', '\0' }; 2442 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 2443 2444 /* Clear screen and move to top left */ 2445 printf("%s%s", clr, top_left); 2446 2447 printf("\nPort statistics ===================================="); 2448 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 2449 nic_stats_display(fwd_ports_ids[i]); 2450 } 2451 2452 static void 2453 signal_handler(int signum) 2454 { 2455 if (signum == SIGINT || signum == SIGTERM) { 2456 printf("\nSignal %d received, preparing to exit...\n", 2457 signum); 2458 #ifdef RTE_LIBRTE_PDUMP 2459 /* uninitialize packet capture framework */ 2460 rte_pdump_uninit(); 2461 #endif 2462 #ifdef RTE_LIBRTE_LATENCY_STATS 2463 rte_latencystats_uninit(); 2464 #endif 2465 force_quit(); 2466 /* Set flag to indicate the force termination. */ 2467 f_quit = 1; 2468 /* exit with the expected status */ 2469 signal(signum, SIG_DFL); 2470 kill(getpid(), signum); 2471 } 2472 } 2473 2474 int 2475 main(int argc, char** argv) 2476 { 2477 int diag; 2478 portid_t port_id; 2479 2480 signal(SIGINT, signal_handler); 2481 signal(SIGTERM, signal_handler); 2482 2483 diag = rte_eal_init(argc, argv); 2484 if (diag < 0) 2485 rte_panic("Cannot init EAL\n"); 2486 2487 testpmd_logtype = rte_log_register("testpmd"); 2488 if (testpmd_logtype < 0) 2489 rte_panic("Cannot register log type"); 2490 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG); 2491 2492 if (mlockall(MCL_CURRENT | MCL_FUTURE)) { 2493 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n", 2494 strerror(errno)); 2495 } 2496 2497 #ifdef RTE_LIBRTE_PDUMP 2498 /* initialize packet capture framework */ 2499 rte_pdump_init(NULL); 2500 #endif 2501 2502 nb_ports = (portid_t) rte_eth_dev_count(); 2503 if (nb_ports == 0) 2504 TESTPMD_LOG(WARNING, "No probed ethernet devices\n"); 2505 2506 /* allocate port structures, and init them */ 2507 init_port(); 2508 2509 set_def_fwd_config(); 2510 if (nb_lcores == 0) 2511 rte_panic("Empty set of forwarding logical cores - check the " 2512 "core mask supplied in the command parameters\n"); 2513 2514 /* Bitrate/latency stats disabled by default */ 2515 #ifdef RTE_LIBRTE_BITRATE 2516 bitrate_enabled = 0; 2517 #endif 2518 #ifdef RTE_LIBRTE_LATENCY_STATS 2519 latencystats_enabled = 0; 2520 #endif 2521 2522 argc -= diag; 2523 argv += diag; 2524 if (argc > 1) 2525 launch_args_parse(argc, argv); 2526 2527 if (tx_first && interactive) 2528 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on " 2529 "interactive mode.\n"); 2530 2531 if (tx_first && lsc_interrupt) { 2532 printf("Warning: lsc_interrupt needs to be off when " 2533 " using tx_first. Disabling.\n"); 2534 lsc_interrupt = 0; 2535 } 2536 2537 if (!nb_rxq && !nb_txq) 2538 printf("Warning: Either rx or tx queues should be non-zero\n"); 2539 2540 if (nb_rxq > 1 && nb_rxq > nb_txq) 2541 printf("Warning: nb_rxq=%d enables RSS configuration, " 2542 "but nb_txq=%d will prevent to fully test it.\n", 2543 nb_rxq, nb_txq); 2544 2545 init_config(); 2546 if (start_port(RTE_PORT_ALL) != 0) 2547 rte_exit(EXIT_FAILURE, "Start ports failed\n"); 2548 2549 /* set all ports to promiscuous mode by default */ 2550 RTE_ETH_FOREACH_DEV(port_id) 2551 rte_eth_promiscuous_enable(port_id); 2552 2553 /* Init metrics library */ 2554 rte_metrics_init(rte_socket_id()); 2555 2556 #ifdef RTE_LIBRTE_LATENCY_STATS 2557 if (latencystats_enabled != 0) { 2558 int ret = rte_latencystats_init(1, NULL); 2559 if (ret) 2560 printf("Warning: latencystats init()" 2561 " returned error %d\n", ret); 2562 printf("Latencystats running on lcore %d\n", 2563 latencystats_lcore_id); 2564 } 2565 #endif 2566 2567 /* Setup bitrate stats */ 2568 #ifdef RTE_LIBRTE_BITRATE 2569 if (bitrate_enabled != 0) { 2570 bitrate_data = rte_stats_bitrate_create(); 2571 if (bitrate_data == NULL) 2572 rte_exit(EXIT_FAILURE, 2573 "Could not allocate bitrate data.\n"); 2574 rte_stats_bitrate_reg(bitrate_data); 2575 } 2576 #endif 2577 2578 #ifdef RTE_LIBRTE_CMDLINE 2579 if (strlen(cmdline_filename) != 0) 2580 cmdline_read_from_file(cmdline_filename); 2581 2582 if (interactive == 1) { 2583 if (auto_start) { 2584 printf("Start automatic packet forwarding\n"); 2585 start_packet_forwarding(0); 2586 } 2587 prompt(); 2588 pmd_test_exit(); 2589 } else 2590 #endif 2591 { 2592 char c; 2593 int rc; 2594 2595 f_quit = 0; 2596 2597 printf("No commandline core given, start packet forwarding\n"); 2598 start_packet_forwarding(tx_first); 2599 if (stats_period != 0) { 2600 uint64_t prev_time = 0, cur_time, diff_time = 0; 2601 uint64_t timer_period; 2602 2603 /* Convert to number of cycles */ 2604 timer_period = stats_period * rte_get_timer_hz(); 2605 2606 while (f_quit == 0) { 2607 cur_time = rte_get_timer_cycles(); 2608 diff_time += cur_time - prev_time; 2609 2610 if (diff_time >= timer_period) { 2611 print_stats(); 2612 /* Reset the timer */ 2613 diff_time = 0; 2614 } 2615 /* Sleep to avoid unnecessary checks */ 2616 prev_time = cur_time; 2617 sleep(1); 2618 } 2619 } 2620 2621 printf("Press enter to exit\n"); 2622 rc = read(0, &c, 1); 2623 pmd_test_exit(); 2624 if (rc < 0) 2625 return 1; 2626 } 2627 2628 return 0; 2629 } 2630