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