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