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