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 #ifndef MAP_HUGETLB 67 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */ 68 #define HUGE_FLAG (0x40000) 69 #else 70 #define HUGE_FLAG MAP_HUGETLB 71 #endif 72 73 #ifndef MAP_HUGE_SHIFT 74 /* older kernels (or FreeBSD) will not have this define */ 75 #define HUGE_SHIFT (26) 76 #else 77 #define HUGE_SHIFT MAP_HUGE_SHIFT 78 #endif 79 80 #define EXTMEM_HEAP_NAME "extmem" 81 #define EXTBUF_ZONE_SIZE RTE_PGSIZE_2M 82 83 uint16_t verbose_level = 0; /**< Silent by default. */ 84 int testpmd_logtype; /**< Log type for testpmd logs */ 85 86 /* use master core for command line ? */ 87 uint8_t interactive = 0; 88 uint8_t auto_start = 0; 89 uint8_t tx_first; 90 char cmdline_filename[PATH_MAX] = {0}; 91 92 /* 93 * NUMA support configuration. 94 * When set, the NUMA support attempts to dispatch the allocation of the 95 * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the 96 * probed ports among the CPU sockets 0 and 1. 97 * Otherwise, all memory is allocated from CPU socket 0. 98 */ 99 uint8_t numa_support = 1; /**< numa enabled by default */ 100 101 /* 102 * In UMA mode,all memory is allocated from socket 0 if --socket-num is 103 * not configured. 104 */ 105 uint8_t socket_num = UMA_NO_CONFIG; 106 107 /* 108 * Select mempool allocation type: 109 * - native: use regular DPDK memory 110 * - anon: use regular DPDK memory to create mempool, but populate using 111 * anonymous memory (may not be IOVA-contiguous) 112 * - xmem: use externally allocated hugepage memory 113 */ 114 uint8_t mp_alloc_type = MP_ALLOC_NATIVE; 115 116 /* 117 * Store specified sockets on which memory pool to be used by ports 118 * is allocated. 119 */ 120 uint8_t port_numa[RTE_MAX_ETHPORTS]; 121 122 /* 123 * Store specified sockets on which RX ring to be used by ports 124 * is allocated. 125 */ 126 uint8_t rxring_numa[RTE_MAX_ETHPORTS]; 127 128 /* 129 * Store specified sockets on which TX ring to be used by ports 130 * is allocated. 131 */ 132 uint8_t txring_numa[RTE_MAX_ETHPORTS]; 133 134 /* 135 * Record the Ethernet address of peer target ports to which packets are 136 * forwarded. 137 * Must be instantiated with the ethernet addresses of peer traffic generator 138 * ports. 139 */ 140 struct rte_ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; 141 portid_t nb_peer_eth_addrs = 0; 142 143 /* 144 * Probed Target Environment. 145 */ 146 struct rte_port *ports; /**< For all probed ethernet ports. */ 147 portid_t nb_ports; /**< Number of probed ethernet ports. */ 148 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */ 149 lcoreid_t nb_lcores; /**< Number of probed logical cores. */ 150 151 portid_t ports_ids[RTE_MAX_ETHPORTS]; /**< Store all port ids. */ 152 153 /* 154 * Test Forwarding Configuration. 155 * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores 156 * nb_fwd_ports <= nb_cfg_ports <= nb_ports 157 */ 158 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */ 159 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */ 160 portid_t nb_cfg_ports; /**< Number of configured ports. */ 161 portid_t nb_fwd_ports; /**< Number of forwarding ports. */ 162 163 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */ 164 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */ 165 166 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */ 167 streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ 168 169 /* 170 * Forwarding engines. 171 */ 172 struct fwd_engine * fwd_engines[] = { 173 &io_fwd_engine, 174 &mac_fwd_engine, 175 &mac_swap_engine, 176 &flow_gen_engine, 177 &rx_only_engine, 178 &tx_only_engine, 179 &csum_fwd_engine, 180 &icmp_echo_engine, 181 &noisy_vnf_engine, 182 #if defined RTE_LIBRTE_PMD_SOFTNIC 183 &softnic_fwd_engine, 184 #endif 185 #ifdef RTE_LIBRTE_IEEE1588 186 &ieee1588_fwd_engine, 187 #endif 188 NULL, 189 }; 190 191 struct rte_mempool *mempools[RTE_MAX_NUMA_NODES]; 192 uint16_t mempool_flags; 193 194 struct fwd_config cur_fwd_config; 195 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ 196 uint32_t retry_enabled; 197 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; 198 uint32_t burst_tx_retry_num = BURST_TX_RETRIES; 199 200 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ 201 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if 202 * specified on command-line. */ 203 uint16_t stats_period; /**< Period to show statistics (disabled by default) */ 204 205 /* 206 * In container, it cannot terminate the process which running with 'stats-period' 207 * option. Set flag to exit stats period loop after received SIGINT/SIGTERM. 208 */ 209 uint8_t f_quit; 210 211 /* 212 * Configuration of packet segments used by the "txonly" processing engine. 213 */ 214 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */ 215 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = { 216 TXONLY_DEF_PACKET_LEN, 217 }; 218 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */ 219 220 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF; 221 /**< Split policy for packets to TX. */ 222 223 uint8_t txonly_multi_flow; 224 /**< Whether multiple flows are generated in TXONLY mode. */ 225 226 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */ 227 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */ 228 229 /* current configuration is in DCB or not,0 means it is not in DCB mode */ 230 uint8_t dcb_config = 0; 231 232 /* Whether the dcb is in testing status */ 233 uint8_t dcb_test = 0; 234 235 /* 236 * Configurable number of RX/TX queues. 237 */ 238 queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */ 239 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ 240 queueid_t nb_txq = 1; /**< Number of TX queues per port. */ 241 242 /* 243 * Configurable number of RX/TX ring descriptors. 244 * Defaults are supplied by drivers via ethdev. 245 */ 246 #define RTE_TEST_RX_DESC_DEFAULT 0 247 #define RTE_TEST_TX_DESC_DEFAULT 0 248 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */ 249 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */ 250 251 #define RTE_PMD_PARAM_UNSET -1 252 /* 253 * Configurable values of RX and TX ring threshold registers. 254 */ 255 256 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET; 257 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET; 258 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET; 259 260 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET; 261 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET; 262 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET; 263 264 /* 265 * Configurable value of RX free threshold. 266 */ 267 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET; 268 269 /* 270 * Configurable value of RX drop enable. 271 */ 272 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET; 273 274 /* 275 * Configurable value of TX free threshold. 276 */ 277 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET; 278 279 /* 280 * Configurable value of TX RS bit threshold. 281 */ 282 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET; 283 284 /* 285 * Configurable value of buffered packets before sending. 286 */ 287 uint16_t noisy_tx_sw_bufsz; 288 289 /* 290 * Configurable value of packet buffer timeout. 291 */ 292 uint16_t noisy_tx_sw_buf_flush_time; 293 294 /* 295 * Configurable value for size of VNF internal memory area 296 * used for simulating noisy neighbour behaviour 297 */ 298 uint64_t noisy_lkup_mem_sz; 299 300 /* 301 * Configurable value of number of random writes done in 302 * VNF simulation memory area. 303 */ 304 uint64_t noisy_lkup_num_writes; 305 306 /* 307 * Configurable value of number of random reads done in 308 * VNF simulation memory area. 309 */ 310 uint64_t noisy_lkup_num_reads; 311 312 /* 313 * Configurable value of number of random reads/writes done in 314 * VNF simulation memory area. 315 */ 316 uint64_t noisy_lkup_num_reads_writes; 317 318 /* 319 * Receive Side Scaling (RSS) configuration. 320 */ 321 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */ 322 323 /* 324 * Port topology configuration 325 */ 326 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */ 327 328 /* 329 * Avoids to flush all the RX streams before starts forwarding. 330 */ 331 uint8_t no_flush_rx = 0; /* flush by default */ 332 333 /* 334 * Flow API isolated mode. 335 */ 336 uint8_t flow_isolate_all; 337 338 /* 339 * Avoids to check link status when starting/stopping a port. 340 */ 341 uint8_t no_link_check = 0; /* check by default */ 342 343 /* 344 * Don't automatically start all ports in interactive mode. 345 */ 346 uint8_t no_device_start = 0; 347 348 /* 349 * Enable link status change notification 350 */ 351 uint8_t lsc_interrupt = 1; /* enabled by default */ 352 353 /* 354 * Enable device removal notification. 355 */ 356 uint8_t rmv_interrupt = 1; /* enabled by default */ 357 358 uint8_t hot_plug = 0; /**< hotplug disabled by default. */ 359 360 /* After attach, port setup is called on event or by iterator */ 361 bool setup_on_probe_event = true; 362 363 /* Clear ptypes on port initialization. */ 364 uint8_t clear_ptypes = true; 365 366 /* Pretty printing of ethdev events */ 367 static const char * const eth_event_desc[] = { 368 [RTE_ETH_EVENT_UNKNOWN] = "unknown", 369 [RTE_ETH_EVENT_INTR_LSC] = "link state change", 370 [RTE_ETH_EVENT_QUEUE_STATE] = "queue state", 371 [RTE_ETH_EVENT_INTR_RESET] = "reset", 372 [RTE_ETH_EVENT_VF_MBOX] = "VF mbox", 373 [RTE_ETH_EVENT_IPSEC] = "IPsec", 374 [RTE_ETH_EVENT_MACSEC] = "MACsec", 375 [RTE_ETH_EVENT_INTR_RMV] = "device removal", 376 [RTE_ETH_EVENT_NEW] = "device probed", 377 [RTE_ETH_EVENT_DESTROY] = "device released", 378 [RTE_ETH_EVENT_FLOW_AGED] = "flow aged", 379 [RTE_ETH_EVENT_MAX] = NULL, 380 }; 381 382 /* 383 * Display or mask ether events 384 * Default to all events except VF_MBOX 385 */ 386 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) | 387 (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) | 388 (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) | 389 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) | 390 (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) | 391 (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) | 392 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV) | 393 (UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED); 394 /* 395 * Decide if all memory are locked for performance. 396 */ 397 int do_mlockall = 0; 398 399 /* 400 * NIC bypass mode configuration options. 401 */ 402 403 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS 404 /* The NIC bypass watchdog timeout. */ 405 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF; 406 #endif 407 408 409 #ifdef RTE_LIBRTE_LATENCY_STATS 410 411 /* 412 * Set when latency stats is enabled in the commandline 413 */ 414 uint8_t latencystats_enabled; 415 416 /* 417 * Lcore ID to serive latency statistics. 418 */ 419 lcoreid_t latencystats_lcore_id = -1; 420 421 #endif 422 423 /* 424 * Ethernet device configuration. 425 */ 426 struct rte_eth_rxmode rx_mode = { 427 .max_rx_pkt_len = RTE_ETHER_MAX_LEN, 428 /**< Default maximum frame length. */ 429 }; 430 431 struct rte_eth_txmode tx_mode = { 432 .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE, 433 }; 434 435 struct rte_fdir_conf fdir_conf = { 436 .mode = RTE_FDIR_MODE_NONE, 437 .pballoc = RTE_FDIR_PBALLOC_64K, 438 .status = RTE_FDIR_REPORT_STATUS, 439 .mask = { 440 .vlan_tci_mask = 0xFFEF, 441 .ipv4_mask = { 442 .src_ip = 0xFFFFFFFF, 443 .dst_ip = 0xFFFFFFFF, 444 }, 445 .ipv6_mask = { 446 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 447 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, 448 }, 449 .src_port_mask = 0xFFFF, 450 .dst_port_mask = 0xFFFF, 451 .mac_addr_byte_mask = 0xFF, 452 .tunnel_type_mask = 1, 453 .tunnel_id_mask = 0xFFFFFFFF, 454 }, 455 .drop_queue = 127, 456 }; 457 458 volatile int test_done = 1; /* stop packet forwarding when set to 1. */ 459 460 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS]; 461 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS]; 462 463 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array; 464 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array; 465 466 uint16_t nb_tx_queue_stats_mappings = 0; 467 uint16_t nb_rx_queue_stats_mappings = 0; 468 469 /* 470 * Display zero values by default for xstats 471 */ 472 uint8_t xstats_hide_zero; 473 474 unsigned int num_sockets = 0; 475 unsigned int socket_ids[RTE_MAX_NUMA_NODES]; 476 477 #ifdef RTE_LIBRTE_BITRATE 478 /* Bitrate statistics */ 479 struct rte_stats_bitrates *bitrate_data; 480 lcoreid_t bitrate_lcore_id; 481 uint8_t bitrate_enabled; 482 #endif 483 484 struct gro_status gro_ports[RTE_MAX_ETHPORTS]; 485 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES; 486 487 /* Forward function declarations */ 488 static void setup_attached_port(portid_t pi); 489 static void map_port_queue_stats_mapping_registers(portid_t pi, 490 struct rte_port *port); 491 static void check_all_ports_link_status(uint32_t port_mask); 492 static int eth_event_callback(portid_t port_id, 493 enum rte_eth_event_type type, 494 void *param, void *ret_param); 495 static void dev_event_callback(const char *device_name, 496 enum rte_dev_event_type type, 497 void *param); 498 499 /* 500 * Check if all the ports are started. 501 * If yes, return positive value. If not, return zero. 502 */ 503 static int all_ports_started(void); 504 505 struct gso_status gso_ports[RTE_MAX_ETHPORTS]; 506 uint16_t gso_max_segment_size = RTE_ETHER_MAX_LEN - RTE_ETHER_CRC_LEN; 507 508 /* Holds the registered mbuf dynamic flags names. */ 509 char dynf_names[64][RTE_MBUF_DYN_NAMESIZE]; 510 511 /* 512 * Helper function to check if socket is already discovered. 513 * If yes, return positive value. If not, return zero. 514 */ 515 int 516 new_socket_id(unsigned int socket_id) 517 { 518 unsigned int i; 519 520 for (i = 0; i < num_sockets; i++) { 521 if (socket_ids[i] == socket_id) 522 return 0; 523 } 524 return 1; 525 } 526 527 /* 528 * Setup default configuration. 529 */ 530 static void 531 set_default_fwd_lcores_config(void) 532 { 533 unsigned int i; 534 unsigned int nb_lc; 535 unsigned int sock_num; 536 537 nb_lc = 0; 538 for (i = 0; i < RTE_MAX_LCORE; i++) { 539 if (!rte_lcore_is_enabled(i)) 540 continue; 541 sock_num = rte_lcore_to_socket_id(i); 542 if (new_socket_id(sock_num)) { 543 if (num_sockets >= RTE_MAX_NUMA_NODES) { 544 rte_exit(EXIT_FAILURE, 545 "Total sockets greater than %u\n", 546 RTE_MAX_NUMA_NODES); 547 } 548 socket_ids[num_sockets++] = sock_num; 549 } 550 if (i == rte_get_master_lcore()) 551 continue; 552 fwd_lcores_cpuids[nb_lc++] = i; 553 } 554 nb_lcores = (lcoreid_t) nb_lc; 555 nb_cfg_lcores = nb_lcores; 556 nb_fwd_lcores = 1; 557 } 558 559 static void 560 set_def_peer_eth_addrs(void) 561 { 562 portid_t i; 563 564 for (i = 0; i < RTE_MAX_ETHPORTS; i++) { 565 peer_eth_addrs[i].addr_bytes[0] = RTE_ETHER_LOCAL_ADMIN_ADDR; 566 peer_eth_addrs[i].addr_bytes[5] = i; 567 } 568 } 569 570 static void 571 set_default_fwd_ports_config(void) 572 { 573 portid_t pt_id; 574 int i = 0; 575 576 RTE_ETH_FOREACH_DEV(pt_id) { 577 fwd_ports_ids[i++] = pt_id; 578 579 /* Update sockets info according to the attached device */ 580 int socket_id = rte_eth_dev_socket_id(pt_id); 581 if (socket_id >= 0 && new_socket_id(socket_id)) { 582 if (num_sockets >= RTE_MAX_NUMA_NODES) { 583 rte_exit(EXIT_FAILURE, 584 "Total sockets greater than %u\n", 585 RTE_MAX_NUMA_NODES); 586 } 587 socket_ids[num_sockets++] = socket_id; 588 } 589 } 590 591 nb_cfg_ports = nb_ports; 592 nb_fwd_ports = nb_ports; 593 } 594 595 void 596 set_def_fwd_config(void) 597 { 598 set_default_fwd_lcores_config(); 599 set_def_peer_eth_addrs(); 600 set_default_fwd_ports_config(); 601 } 602 603 /* extremely pessimistic estimation of memory required to create a mempool */ 604 static int 605 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out) 606 { 607 unsigned int n_pages, mbuf_per_pg, leftover; 608 uint64_t total_mem, mbuf_mem, obj_sz; 609 610 /* there is no good way to predict how much space the mempool will 611 * occupy because it will allocate chunks on the fly, and some of those 612 * will come from default DPDK memory while some will come from our 613 * external memory, so just assume 128MB will be enough for everyone. 614 */ 615 uint64_t hdr_mem = 128 << 20; 616 617 /* account for possible non-contiguousness */ 618 obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL); 619 if (obj_sz > pgsz) { 620 TESTPMD_LOG(ERR, "Object size is bigger than page size\n"); 621 return -1; 622 } 623 624 mbuf_per_pg = pgsz / obj_sz; 625 leftover = (nb_mbufs % mbuf_per_pg) > 0; 626 n_pages = (nb_mbufs / mbuf_per_pg) + leftover; 627 628 mbuf_mem = n_pages * pgsz; 629 630 total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz); 631 632 if (total_mem > SIZE_MAX) { 633 TESTPMD_LOG(ERR, "Memory size too big\n"); 634 return -1; 635 } 636 *out = (size_t)total_mem; 637 638 return 0; 639 } 640 641 static int 642 pagesz_flags(uint64_t page_sz) 643 { 644 /* as per mmap() manpage, all page sizes are log2 of page size 645 * shifted by MAP_HUGE_SHIFT 646 */ 647 int log2 = rte_log2_u64(page_sz); 648 649 return (log2 << HUGE_SHIFT); 650 } 651 652 static void * 653 alloc_mem(size_t memsz, size_t pgsz, bool huge) 654 { 655 void *addr; 656 int flags; 657 658 /* allocate anonymous hugepages */ 659 flags = MAP_ANONYMOUS | MAP_PRIVATE; 660 if (huge) 661 flags |= HUGE_FLAG | pagesz_flags(pgsz); 662 663 addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0); 664 if (addr == MAP_FAILED) 665 return NULL; 666 667 return addr; 668 } 669 670 struct extmem_param { 671 void *addr; 672 size_t len; 673 size_t pgsz; 674 rte_iova_t *iova_table; 675 unsigned int iova_table_len; 676 }; 677 678 static int 679 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param, 680 bool huge) 681 { 682 uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */ 683 RTE_PGSIZE_16M, RTE_PGSIZE_16G}; /* POWER */ 684 unsigned int cur_page, n_pages, pgsz_idx; 685 size_t mem_sz, cur_pgsz; 686 rte_iova_t *iovas = NULL; 687 void *addr; 688 int ret; 689 690 for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) { 691 /* skip anything that is too big */ 692 if (pgsizes[pgsz_idx] > SIZE_MAX) 693 continue; 694 695 cur_pgsz = pgsizes[pgsz_idx]; 696 697 /* if we were told not to allocate hugepages, override */ 698 if (!huge) 699 cur_pgsz = sysconf(_SC_PAGESIZE); 700 701 ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz); 702 if (ret < 0) { 703 TESTPMD_LOG(ERR, "Cannot calculate memory size\n"); 704 return -1; 705 } 706 707 /* allocate our memory */ 708 addr = alloc_mem(mem_sz, cur_pgsz, huge); 709 710 /* if we couldn't allocate memory with a specified page size, 711 * that doesn't mean we can't do it with other page sizes, so 712 * try another one. 713 */ 714 if (addr == NULL) 715 continue; 716 717 /* store IOVA addresses for every page in this memory area */ 718 n_pages = mem_sz / cur_pgsz; 719 720 iovas = malloc(sizeof(*iovas) * n_pages); 721 722 if (iovas == NULL) { 723 TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n"); 724 goto fail; 725 } 726 /* lock memory if it's not huge pages */ 727 if (!huge) 728 mlock(addr, mem_sz); 729 730 /* populate IOVA addresses */ 731 for (cur_page = 0; cur_page < n_pages; cur_page++) { 732 rte_iova_t iova; 733 size_t offset; 734 void *cur; 735 736 offset = cur_pgsz * cur_page; 737 cur = RTE_PTR_ADD(addr, offset); 738 739 /* touch the page before getting its IOVA */ 740 *(volatile char *)cur = 0; 741 742 iova = rte_mem_virt2iova(cur); 743 744 iovas[cur_page] = iova; 745 } 746 747 break; 748 } 749 /* if we couldn't allocate anything */ 750 if (iovas == NULL) 751 return -1; 752 753 param->addr = addr; 754 param->len = mem_sz; 755 param->pgsz = cur_pgsz; 756 param->iova_table = iovas; 757 param->iova_table_len = n_pages; 758 759 return 0; 760 fail: 761 if (iovas) 762 free(iovas); 763 if (addr) 764 munmap(addr, mem_sz); 765 766 return -1; 767 } 768 769 static int 770 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge) 771 { 772 struct extmem_param param; 773 int socket_id, ret; 774 775 memset(¶m, 0, sizeof(param)); 776 777 /* check if our heap exists */ 778 socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME); 779 if (socket_id < 0) { 780 /* create our heap */ 781 ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME); 782 if (ret < 0) { 783 TESTPMD_LOG(ERR, "Cannot create heap\n"); 784 return -1; 785 } 786 } 787 788 ret = create_extmem(nb_mbufs, mbuf_sz, ¶m, huge); 789 if (ret < 0) { 790 TESTPMD_LOG(ERR, "Cannot create memory area\n"); 791 return -1; 792 } 793 794 /* we now have a valid memory area, so add it to heap */ 795 ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME, 796 param.addr, param.len, param.iova_table, 797 param.iova_table_len, param.pgsz); 798 799 /* when using VFIO, memory is automatically mapped for DMA by EAL */ 800 801 /* not needed any more */ 802 free(param.iova_table); 803 804 if (ret < 0) { 805 TESTPMD_LOG(ERR, "Cannot add memory to heap\n"); 806 munmap(param.addr, param.len); 807 return -1; 808 } 809 810 /* success */ 811 812 TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n", 813 param.len >> 20); 814 815 return 0; 816 } 817 static void 818 dma_unmap_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused, 819 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused) 820 { 821 uint16_t pid = 0; 822 int ret; 823 824 RTE_ETH_FOREACH_DEV(pid) { 825 struct rte_eth_dev *dev = 826 &rte_eth_devices[pid]; 827 828 ret = rte_dev_dma_unmap(dev->device, memhdr->addr, 0, 829 memhdr->len); 830 if (ret) { 831 TESTPMD_LOG(DEBUG, 832 "unable to DMA unmap addr 0x%p " 833 "for device %s\n", 834 memhdr->addr, dev->data->name); 835 } 836 } 837 ret = rte_extmem_unregister(memhdr->addr, memhdr->len); 838 if (ret) { 839 TESTPMD_LOG(DEBUG, 840 "unable to un-register addr 0x%p\n", memhdr->addr); 841 } 842 } 843 844 static void 845 dma_map_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused, 846 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused) 847 { 848 uint16_t pid = 0; 849 size_t page_size = sysconf(_SC_PAGESIZE); 850 int ret; 851 852 ret = rte_extmem_register(memhdr->addr, memhdr->len, NULL, 0, 853 page_size); 854 if (ret) { 855 TESTPMD_LOG(DEBUG, 856 "unable to register addr 0x%p\n", memhdr->addr); 857 return; 858 } 859 RTE_ETH_FOREACH_DEV(pid) { 860 struct rte_eth_dev *dev = 861 &rte_eth_devices[pid]; 862 863 ret = rte_dev_dma_map(dev->device, memhdr->addr, 0, 864 memhdr->len); 865 if (ret) { 866 TESTPMD_LOG(DEBUG, 867 "unable to DMA map addr 0x%p " 868 "for device %s\n", 869 memhdr->addr, dev->data->name); 870 } 871 } 872 } 873 874 static unsigned int 875 setup_extbuf(uint32_t nb_mbufs, uint16_t mbuf_sz, unsigned int socket_id, 876 char *pool_name, struct rte_pktmbuf_extmem **ext_mem) 877 { 878 struct rte_pktmbuf_extmem *xmem; 879 unsigned int ext_num, zone_num, elt_num; 880 uint16_t elt_size; 881 882 elt_size = RTE_ALIGN_CEIL(mbuf_sz, RTE_CACHE_LINE_SIZE); 883 elt_num = EXTBUF_ZONE_SIZE / elt_size; 884 zone_num = (nb_mbufs + elt_num - 1) / elt_num; 885 886 xmem = malloc(sizeof(struct rte_pktmbuf_extmem) * zone_num); 887 if (xmem == NULL) { 888 TESTPMD_LOG(ERR, "Cannot allocate memory for " 889 "external buffer descriptors\n"); 890 *ext_mem = NULL; 891 return 0; 892 } 893 for (ext_num = 0; ext_num < zone_num; ext_num++) { 894 struct rte_pktmbuf_extmem *xseg = xmem + ext_num; 895 const struct rte_memzone *mz; 896 char mz_name[RTE_MEMZONE_NAMESIZE]; 897 int ret; 898 899 ret = snprintf(mz_name, sizeof(mz_name), 900 RTE_MEMPOOL_MZ_FORMAT "_xb_%u", pool_name, ext_num); 901 if (ret < 0 || ret >= (int)sizeof(mz_name)) { 902 errno = ENAMETOOLONG; 903 ext_num = 0; 904 break; 905 } 906 mz = rte_memzone_reserve_aligned(mz_name, EXTBUF_ZONE_SIZE, 907 socket_id, 908 RTE_MEMZONE_IOVA_CONTIG | 909 RTE_MEMZONE_1GB | 910 RTE_MEMZONE_SIZE_HINT_ONLY, 911 EXTBUF_ZONE_SIZE); 912 if (mz == NULL) { 913 /* 914 * The caller exits on external buffer creation 915 * error, so there is no need to free memzones. 916 */ 917 errno = ENOMEM; 918 ext_num = 0; 919 break; 920 } 921 xseg->buf_ptr = mz->addr; 922 xseg->buf_iova = mz->iova; 923 xseg->buf_len = EXTBUF_ZONE_SIZE; 924 xseg->elt_size = elt_size; 925 } 926 if (ext_num == 0 && xmem != NULL) { 927 free(xmem); 928 xmem = NULL; 929 } 930 *ext_mem = xmem; 931 return ext_num; 932 } 933 934 /* 935 * Configuration initialisation done once at init time. 936 */ 937 static struct rte_mempool * 938 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, 939 unsigned int socket_id) 940 { 941 char pool_name[RTE_MEMPOOL_NAMESIZE]; 942 struct rte_mempool *rte_mp = NULL; 943 uint32_t mb_size; 944 945 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; 946 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); 947 948 TESTPMD_LOG(INFO, 949 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", 950 pool_name, nb_mbuf, mbuf_seg_size, socket_id); 951 952 switch (mp_alloc_type) { 953 case MP_ALLOC_NATIVE: 954 { 955 /* wrapper to rte_mempool_create() */ 956 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n", 957 rte_mbuf_best_mempool_ops()); 958 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, 959 mb_mempool_cache, 0, mbuf_seg_size, socket_id); 960 break; 961 } 962 case MP_ALLOC_ANON: 963 { 964 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, 965 mb_size, (unsigned int) mb_mempool_cache, 966 sizeof(struct rte_pktmbuf_pool_private), 967 socket_id, mempool_flags); 968 if (rte_mp == NULL) 969 goto err; 970 971 if (rte_mempool_populate_anon(rte_mp) == 0) { 972 rte_mempool_free(rte_mp); 973 rte_mp = NULL; 974 goto err; 975 } 976 rte_pktmbuf_pool_init(rte_mp, NULL); 977 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); 978 rte_mempool_mem_iter(rte_mp, dma_map_cb, NULL); 979 break; 980 } 981 case MP_ALLOC_XMEM: 982 case MP_ALLOC_XMEM_HUGE: 983 { 984 int heap_socket; 985 bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE; 986 987 if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0) 988 rte_exit(EXIT_FAILURE, "Could not create external memory\n"); 989 990 heap_socket = 991 rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME); 992 if (heap_socket < 0) 993 rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n"); 994 995 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n", 996 rte_mbuf_best_mempool_ops()); 997 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, 998 mb_mempool_cache, 0, mbuf_seg_size, 999 heap_socket); 1000 break; 1001 } 1002 case MP_ALLOC_XBUF: 1003 { 1004 struct rte_pktmbuf_extmem *ext_mem; 1005 unsigned int ext_num; 1006 1007 ext_num = setup_extbuf(nb_mbuf, mbuf_seg_size, 1008 socket_id, pool_name, &ext_mem); 1009 if (ext_num == 0) 1010 rte_exit(EXIT_FAILURE, 1011 "Can't create pinned data buffers\n"); 1012 1013 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n", 1014 rte_mbuf_best_mempool_ops()); 1015 rte_mp = rte_pktmbuf_pool_create_extbuf 1016 (pool_name, nb_mbuf, mb_mempool_cache, 1017 0, mbuf_seg_size, socket_id, 1018 ext_mem, ext_num); 1019 free(ext_mem); 1020 break; 1021 } 1022 default: 1023 { 1024 rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n"); 1025 } 1026 } 1027 1028 err: 1029 if (rte_mp == NULL) { 1030 rte_exit(EXIT_FAILURE, 1031 "Creation of mbuf pool for socket %u failed: %s\n", 1032 socket_id, rte_strerror(rte_errno)); 1033 } else if (verbose_level > 0) { 1034 rte_mempool_dump(stdout, rte_mp); 1035 } 1036 return rte_mp; 1037 } 1038 1039 /* 1040 * Check given socket id is valid or not with NUMA mode, 1041 * if valid, return 0, else return -1 1042 */ 1043 static int 1044 check_socket_id(const unsigned int socket_id) 1045 { 1046 static int warning_once = 0; 1047 1048 if (new_socket_id(socket_id)) { 1049 if (!warning_once && numa_support) 1050 printf("Warning: NUMA should be configured manually by" 1051 " using --port-numa-config and" 1052 " --ring-numa-config parameters along with" 1053 " --numa.\n"); 1054 warning_once = 1; 1055 return -1; 1056 } 1057 return 0; 1058 } 1059 1060 /* 1061 * Get the allowed maximum number of RX queues. 1062 * *pid return the port id which has minimal value of 1063 * max_rx_queues in all ports. 1064 */ 1065 queueid_t 1066 get_allowed_max_nb_rxq(portid_t *pid) 1067 { 1068 queueid_t allowed_max_rxq = RTE_MAX_QUEUES_PER_PORT; 1069 bool max_rxq_valid = false; 1070 portid_t pi; 1071 struct rte_eth_dev_info dev_info; 1072 1073 RTE_ETH_FOREACH_DEV(pi) { 1074 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1075 continue; 1076 1077 max_rxq_valid = true; 1078 if (dev_info.max_rx_queues < allowed_max_rxq) { 1079 allowed_max_rxq = dev_info.max_rx_queues; 1080 *pid = pi; 1081 } 1082 } 1083 return max_rxq_valid ? allowed_max_rxq : 0; 1084 } 1085 1086 /* 1087 * Check input rxq is valid or not. 1088 * If input rxq is not greater than any of maximum number 1089 * of RX queues of all ports, it is valid. 1090 * if valid, return 0, else return -1 1091 */ 1092 int 1093 check_nb_rxq(queueid_t rxq) 1094 { 1095 queueid_t allowed_max_rxq; 1096 portid_t pid = 0; 1097 1098 allowed_max_rxq = get_allowed_max_nb_rxq(&pid); 1099 if (rxq > allowed_max_rxq) { 1100 printf("Fail: input rxq (%u) can't be greater " 1101 "than max_rx_queues (%u) of port %u\n", 1102 rxq, 1103 allowed_max_rxq, 1104 pid); 1105 return -1; 1106 } 1107 return 0; 1108 } 1109 1110 /* 1111 * Get the allowed maximum number of TX queues. 1112 * *pid return the port id which has minimal value of 1113 * max_tx_queues in all ports. 1114 */ 1115 queueid_t 1116 get_allowed_max_nb_txq(portid_t *pid) 1117 { 1118 queueid_t allowed_max_txq = RTE_MAX_QUEUES_PER_PORT; 1119 bool max_txq_valid = false; 1120 portid_t pi; 1121 struct rte_eth_dev_info dev_info; 1122 1123 RTE_ETH_FOREACH_DEV(pi) { 1124 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1125 continue; 1126 1127 max_txq_valid = true; 1128 if (dev_info.max_tx_queues < allowed_max_txq) { 1129 allowed_max_txq = dev_info.max_tx_queues; 1130 *pid = pi; 1131 } 1132 } 1133 return max_txq_valid ? allowed_max_txq : 0; 1134 } 1135 1136 /* 1137 * Check input txq is valid or not. 1138 * If input txq is not greater than any of maximum number 1139 * of TX queues of all ports, it is valid. 1140 * if valid, return 0, else return -1 1141 */ 1142 int 1143 check_nb_txq(queueid_t txq) 1144 { 1145 queueid_t allowed_max_txq; 1146 portid_t pid = 0; 1147 1148 allowed_max_txq = get_allowed_max_nb_txq(&pid); 1149 if (txq > allowed_max_txq) { 1150 printf("Fail: input txq (%u) can't be greater " 1151 "than max_tx_queues (%u) of port %u\n", 1152 txq, 1153 allowed_max_txq, 1154 pid); 1155 return -1; 1156 } 1157 return 0; 1158 } 1159 1160 /* 1161 * Get the allowed maximum number of RXDs of every rx queue. 1162 * *pid return the port id which has minimal value of 1163 * max_rxd in all queues of all ports. 1164 */ 1165 static uint16_t 1166 get_allowed_max_nb_rxd(portid_t *pid) 1167 { 1168 uint16_t allowed_max_rxd = UINT16_MAX; 1169 portid_t pi; 1170 struct rte_eth_dev_info dev_info; 1171 1172 RTE_ETH_FOREACH_DEV(pi) { 1173 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1174 continue; 1175 1176 if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) { 1177 allowed_max_rxd = dev_info.rx_desc_lim.nb_max; 1178 *pid = pi; 1179 } 1180 } 1181 return allowed_max_rxd; 1182 } 1183 1184 /* 1185 * Get the allowed minimal number of RXDs of every rx queue. 1186 * *pid return the port id which has minimal value of 1187 * min_rxd in all queues of all ports. 1188 */ 1189 static uint16_t 1190 get_allowed_min_nb_rxd(portid_t *pid) 1191 { 1192 uint16_t allowed_min_rxd = 0; 1193 portid_t pi; 1194 struct rte_eth_dev_info dev_info; 1195 1196 RTE_ETH_FOREACH_DEV(pi) { 1197 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1198 continue; 1199 1200 if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) { 1201 allowed_min_rxd = dev_info.rx_desc_lim.nb_min; 1202 *pid = pi; 1203 } 1204 } 1205 1206 return allowed_min_rxd; 1207 } 1208 1209 /* 1210 * Check input rxd is valid or not. 1211 * If input rxd is not greater than any of maximum number 1212 * of RXDs of every Rx queues and is not less than any of 1213 * minimal number of RXDs of every Rx queues, it is valid. 1214 * if valid, return 0, else return -1 1215 */ 1216 int 1217 check_nb_rxd(queueid_t rxd) 1218 { 1219 uint16_t allowed_max_rxd; 1220 uint16_t allowed_min_rxd; 1221 portid_t pid = 0; 1222 1223 allowed_max_rxd = get_allowed_max_nb_rxd(&pid); 1224 if (rxd > allowed_max_rxd) { 1225 printf("Fail: input rxd (%u) can't be greater " 1226 "than max_rxds (%u) of port %u\n", 1227 rxd, 1228 allowed_max_rxd, 1229 pid); 1230 return -1; 1231 } 1232 1233 allowed_min_rxd = get_allowed_min_nb_rxd(&pid); 1234 if (rxd < allowed_min_rxd) { 1235 printf("Fail: input rxd (%u) can't be less " 1236 "than min_rxds (%u) of port %u\n", 1237 rxd, 1238 allowed_min_rxd, 1239 pid); 1240 return -1; 1241 } 1242 1243 return 0; 1244 } 1245 1246 /* 1247 * Get the allowed maximum number of TXDs of every rx queues. 1248 * *pid return the port id which has minimal value of 1249 * max_txd in every tx queue. 1250 */ 1251 static uint16_t 1252 get_allowed_max_nb_txd(portid_t *pid) 1253 { 1254 uint16_t allowed_max_txd = UINT16_MAX; 1255 portid_t pi; 1256 struct rte_eth_dev_info dev_info; 1257 1258 RTE_ETH_FOREACH_DEV(pi) { 1259 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1260 continue; 1261 1262 if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) { 1263 allowed_max_txd = dev_info.tx_desc_lim.nb_max; 1264 *pid = pi; 1265 } 1266 } 1267 return allowed_max_txd; 1268 } 1269 1270 /* 1271 * Get the allowed maximum number of TXDs of every tx queues. 1272 * *pid return the port id which has minimal value of 1273 * min_txd in every tx queue. 1274 */ 1275 static uint16_t 1276 get_allowed_min_nb_txd(portid_t *pid) 1277 { 1278 uint16_t allowed_min_txd = 0; 1279 portid_t pi; 1280 struct rte_eth_dev_info dev_info; 1281 1282 RTE_ETH_FOREACH_DEV(pi) { 1283 if (eth_dev_info_get_print_err(pi, &dev_info) != 0) 1284 continue; 1285 1286 if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) { 1287 allowed_min_txd = dev_info.tx_desc_lim.nb_min; 1288 *pid = pi; 1289 } 1290 } 1291 1292 return allowed_min_txd; 1293 } 1294 1295 /* 1296 * Check input txd is valid or not. 1297 * If input txd is not greater than any of maximum number 1298 * of TXDs of every Rx queues, it is valid. 1299 * if valid, return 0, else return -1 1300 */ 1301 int 1302 check_nb_txd(queueid_t txd) 1303 { 1304 uint16_t allowed_max_txd; 1305 uint16_t allowed_min_txd; 1306 portid_t pid = 0; 1307 1308 allowed_max_txd = get_allowed_max_nb_txd(&pid); 1309 if (txd > allowed_max_txd) { 1310 printf("Fail: input txd (%u) can't be greater " 1311 "than max_txds (%u) of port %u\n", 1312 txd, 1313 allowed_max_txd, 1314 pid); 1315 return -1; 1316 } 1317 1318 allowed_min_txd = get_allowed_min_nb_txd(&pid); 1319 if (txd < allowed_min_txd) { 1320 printf("Fail: input txd (%u) can't be less " 1321 "than min_txds (%u) of port %u\n", 1322 txd, 1323 allowed_min_txd, 1324 pid); 1325 return -1; 1326 } 1327 return 0; 1328 } 1329 1330 1331 /* 1332 * Get the allowed maximum number of hairpin queues. 1333 * *pid return the port id which has minimal value of 1334 * max_hairpin_queues in all ports. 1335 */ 1336 queueid_t 1337 get_allowed_max_nb_hairpinq(portid_t *pid) 1338 { 1339 queueid_t allowed_max_hairpinq = RTE_MAX_QUEUES_PER_PORT; 1340 portid_t pi; 1341 struct rte_eth_hairpin_cap cap; 1342 1343 RTE_ETH_FOREACH_DEV(pi) { 1344 if (rte_eth_dev_hairpin_capability_get(pi, &cap) != 0) { 1345 *pid = pi; 1346 return 0; 1347 } 1348 if (cap.max_nb_queues < allowed_max_hairpinq) { 1349 allowed_max_hairpinq = cap.max_nb_queues; 1350 *pid = pi; 1351 } 1352 } 1353 return allowed_max_hairpinq; 1354 } 1355 1356 /* 1357 * Check input hairpin is valid or not. 1358 * If input hairpin is not greater than any of maximum number 1359 * of hairpin queues of all ports, it is valid. 1360 * if valid, return 0, else return -1 1361 */ 1362 int 1363 check_nb_hairpinq(queueid_t hairpinq) 1364 { 1365 queueid_t allowed_max_hairpinq; 1366 portid_t pid = 0; 1367 1368 allowed_max_hairpinq = get_allowed_max_nb_hairpinq(&pid); 1369 if (hairpinq > allowed_max_hairpinq) { 1370 printf("Fail: input hairpin (%u) can't be greater " 1371 "than max_hairpin_queues (%u) of port %u\n", 1372 hairpinq, allowed_max_hairpinq, pid); 1373 return -1; 1374 } 1375 return 0; 1376 } 1377 1378 static void 1379 init_config(void) 1380 { 1381 portid_t pid; 1382 struct rte_port *port; 1383 struct rte_mempool *mbp; 1384 unsigned int nb_mbuf_per_pool; 1385 lcoreid_t lc_id; 1386 uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; 1387 struct rte_gro_param gro_param; 1388 uint32_t gso_types; 1389 uint16_t data_size; 1390 bool warning = 0; 1391 int k; 1392 int ret; 1393 1394 memset(port_per_socket,0,RTE_MAX_NUMA_NODES); 1395 1396 /* Configuration of logical cores. */ 1397 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", 1398 sizeof(struct fwd_lcore *) * nb_lcores, 1399 RTE_CACHE_LINE_SIZE); 1400 if (fwd_lcores == NULL) { 1401 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " 1402 "failed\n", nb_lcores); 1403 } 1404 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 1405 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", 1406 sizeof(struct fwd_lcore), 1407 RTE_CACHE_LINE_SIZE); 1408 if (fwd_lcores[lc_id] == NULL) { 1409 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " 1410 "failed\n"); 1411 } 1412 fwd_lcores[lc_id]->cpuid_idx = lc_id; 1413 } 1414 1415 RTE_ETH_FOREACH_DEV(pid) { 1416 port = &ports[pid]; 1417 /* Apply default TxRx configuration for all ports */ 1418 port->dev_conf.txmode = tx_mode; 1419 port->dev_conf.rxmode = rx_mode; 1420 1421 ret = eth_dev_info_get_print_err(pid, &port->dev_info); 1422 if (ret != 0) 1423 rte_exit(EXIT_FAILURE, 1424 "rte_eth_dev_info_get() failed\n"); 1425 1426 if (!(port->dev_info.tx_offload_capa & 1427 DEV_TX_OFFLOAD_MBUF_FAST_FREE)) 1428 port->dev_conf.txmode.offloads &= 1429 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; 1430 if (numa_support) { 1431 if (port_numa[pid] != NUMA_NO_CONFIG) 1432 port_per_socket[port_numa[pid]]++; 1433 else { 1434 uint32_t socket_id = rte_eth_dev_socket_id(pid); 1435 1436 /* 1437 * if socket_id is invalid, 1438 * set to the first available socket. 1439 */ 1440 if (check_socket_id(socket_id) < 0) 1441 socket_id = socket_ids[0]; 1442 port_per_socket[socket_id]++; 1443 } 1444 } 1445 1446 /* Apply Rx offloads configuration */ 1447 for (k = 0; k < port->dev_info.max_rx_queues; k++) 1448 port->rx_conf[k].offloads = 1449 port->dev_conf.rxmode.offloads; 1450 /* Apply Tx offloads configuration */ 1451 for (k = 0; k < port->dev_info.max_tx_queues; k++) 1452 port->tx_conf[k].offloads = 1453 port->dev_conf.txmode.offloads; 1454 1455 /* set flag to initialize port/queue */ 1456 port->need_reconfig = 1; 1457 port->need_reconfig_queues = 1; 1458 port->tx_metadata = 0; 1459 1460 /* Check for maximum number of segments per MTU. Accordingly 1461 * update the mbuf data size. 1462 */ 1463 if (port->dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX && 1464 port->dev_info.rx_desc_lim.nb_mtu_seg_max != 0) { 1465 data_size = rx_mode.max_rx_pkt_len / 1466 port->dev_info.rx_desc_lim.nb_mtu_seg_max; 1467 1468 if ((data_size + RTE_PKTMBUF_HEADROOM) > 1469 mbuf_data_size) { 1470 mbuf_data_size = data_size + 1471 RTE_PKTMBUF_HEADROOM; 1472 warning = 1; 1473 } 1474 } 1475 } 1476 1477 if (warning) 1478 TESTPMD_LOG(WARNING, "Configured mbuf size %hu\n", 1479 mbuf_data_size); 1480 1481 /* 1482 * Create pools of mbuf. 1483 * If NUMA support is disabled, create a single pool of mbuf in 1484 * socket 0 memory by default. 1485 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. 1486 * 1487 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and 1488 * nb_txd can be configured at run time. 1489 */ 1490 if (param_total_num_mbufs) 1491 nb_mbuf_per_pool = param_total_num_mbufs; 1492 else { 1493 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + 1494 (nb_lcores * mb_mempool_cache) + 1495 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; 1496 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS; 1497 } 1498 1499 if (numa_support) { 1500 uint8_t i; 1501 1502 for (i = 0; i < num_sockets; i++) 1503 mempools[i] = mbuf_pool_create(mbuf_data_size, 1504 nb_mbuf_per_pool, 1505 socket_ids[i]); 1506 } else { 1507 if (socket_num == UMA_NO_CONFIG) 1508 mempools[0] = mbuf_pool_create(mbuf_data_size, 1509 nb_mbuf_per_pool, 0); 1510 else 1511 mempools[socket_num] = mbuf_pool_create 1512 (mbuf_data_size, 1513 nb_mbuf_per_pool, 1514 socket_num); 1515 } 1516 1517 init_port_config(); 1518 1519 gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO | 1520 DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO; 1521 /* 1522 * Records which Mbuf pool to use by each logical core, if needed. 1523 */ 1524 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 1525 mbp = mbuf_pool_find( 1526 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id])); 1527 1528 if (mbp == NULL) 1529 mbp = mbuf_pool_find(0); 1530 fwd_lcores[lc_id]->mbp = mbp; 1531 /* initialize GSO context */ 1532 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp; 1533 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp; 1534 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types; 1535 fwd_lcores[lc_id]->gso_ctx.gso_size = RTE_ETHER_MAX_LEN - 1536 RTE_ETHER_CRC_LEN; 1537 fwd_lcores[lc_id]->gso_ctx.flag = 0; 1538 } 1539 1540 /* Configuration of packet forwarding streams. */ 1541 if (init_fwd_streams() < 0) 1542 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); 1543 1544 fwd_config_setup(); 1545 1546 /* create a gro context for each lcore */ 1547 gro_param.gro_types = RTE_GRO_TCP_IPV4; 1548 gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES; 1549 gro_param.max_item_per_flow = MAX_PKT_BURST; 1550 for (lc_id = 0; lc_id < nb_lcores; lc_id++) { 1551 gro_param.socket_id = rte_lcore_to_socket_id( 1552 fwd_lcores_cpuids[lc_id]); 1553 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param); 1554 if (fwd_lcores[lc_id]->gro_ctx == NULL) { 1555 rte_exit(EXIT_FAILURE, 1556 "rte_gro_ctx_create() failed\n"); 1557 } 1558 } 1559 1560 #if defined RTE_LIBRTE_PMD_SOFTNIC 1561 if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) { 1562 RTE_ETH_FOREACH_DEV(pid) { 1563 port = &ports[pid]; 1564 const char *driver = port->dev_info.driver_name; 1565 1566 if (strcmp(driver, "net_softnic") == 0) 1567 port->softport.fwd_lcore_arg = fwd_lcores; 1568 } 1569 } 1570 #endif 1571 1572 } 1573 1574 1575 void 1576 reconfig(portid_t new_port_id, unsigned socket_id) 1577 { 1578 struct rte_port *port; 1579 int ret; 1580 1581 /* Reconfiguration of Ethernet ports. */ 1582 port = &ports[new_port_id]; 1583 1584 ret = eth_dev_info_get_print_err(new_port_id, &port->dev_info); 1585 if (ret != 0) 1586 return; 1587 1588 /* set flag to initialize port/queue */ 1589 port->need_reconfig = 1; 1590 port->need_reconfig_queues = 1; 1591 port->socket_id = socket_id; 1592 1593 init_port_config(); 1594 } 1595 1596 1597 int 1598 init_fwd_streams(void) 1599 { 1600 portid_t pid; 1601 struct rte_port *port; 1602 streamid_t sm_id, nb_fwd_streams_new; 1603 queueid_t q; 1604 1605 /* set socket id according to numa or not */ 1606 RTE_ETH_FOREACH_DEV(pid) { 1607 port = &ports[pid]; 1608 if (nb_rxq > port->dev_info.max_rx_queues) { 1609 printf("Fail: nb_rxq(%d) is greater than " 1610 "max_rx_queues(%d)\n", nb_rxq, 1611 port->dev_info.max_rx_queues); 1612 return -1; 1613 } 1614 if (nb_txq > port->dev_info.max_tx_queues) { 1615 printf("Fail: nb_txq(%d) is greater than " 1616 "max_tx_queues(%d)\n", nb_txq, 1617 port->dev_info.max_tx_queues); 1618 return -1; 1619 } 1620 if (numa_support) { 1621 if (port_numa[pid] != NUMA_NO_CONFIG) 1622 port->socket_id = port_numa[pid]; 1623 else { 1624 port->socket_id = rte_eth_dev_socket_id(pid); 1625 1626 /* 1627 * if socket_id is invalid, 1628 * set to the first available socket. 1629 */ 1630 if (check_socket_id(port->socket_id) < 0) 1631 port->socket_id = socket_ids[0]; 1632 } 1633 } 1634 else { 1635 if (socket_num == UMA_NO_CONFIG) 1636 port->socket_id = 0; 1637 else 1638 port->socket_id = socket_num; 1639 } 1640 } 1641 1642 q = RTE_MAX(nb_rxq, nb_txq); 1643 if (q == 0) { 1644 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n"); 1645 return -1; 1646 } 1647 nb_fwd_streams_new = (streamid_t)(nb_ports * q); 1648 if (nb_fwd_streams_new == nb_fwd_streams) 1649 return 0; 1650 /* clear the old */ 1651 if (fwd_streams != NULL) { 1652 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 1653 if (fwd_streams[sm_id] == NULL) 1654 continue; 1655 rte_free(fwd_streams[sm_id]); 1656 fwd_streams[sm_id] = NULL; 1657 } 1658 rte_free(fwd_streams); 1659 fwd_streams = NULL; 1660 } 1661 1662 /* init new */ 1663 nb_fwd_streams = nb_fwd_streams_new; 1664 if (nb_fwd_streams) { 1665 fwd_streams = rte_zmalloc("testpmd: fwd_streams", 1666 sizeof(struct fwd_stream *) * nb_fwd_streams, 1667 RTE_CACHE_LINE_SIZE); 1668 if (fwd_streams == NULL) 1669 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d" 1670 " (struct fwd_stream *)) failed\n", 1671 nb_fwd_streams); 1672 1673 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { 1674 fwd_streams[sm_id] = rte_zmalloc("testpmd:" 1675 " struct fwd_stream", sizeof(struct fwd_stream), 1676 RTE_CACHE_LINE_SIZE); 1677 if (fwd_streams[sm_id] == NULL) 1678 rte_exit(EXIT_FAILURE, "rte_zmalloc" 1679 "(struct fwd_stream) failed\n"); 1680 } 1681 } 1682 1683 return 0; 1684 } 1685 1686 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1687 static void 1688 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs) 1689 { 1690 unsigned int total_burst; 1691 unsigned int nb_burst; 1692 unsigned int burst_stats[3]; 1693 uint16_t pktnb_stats[3]; 1694 uint16_t nb_pkt; 1695 int burst_percent[3]; 1696 1697 /* 1698 * First compute the total number of packet bursts and the 1699 * two highest numbers of bursts of the same number of packets. 1700 */ 1701 total_burst = 0; 1702 burst_stats[0] = burst_stats[1] = burst_stats[2] = 0; 1703 pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0; 1704 for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) { 1705 nb_burst = pbs->pkt_burst_spread[nb_pkt]; 1706 if (nb_burst == 0) 1707 continue; 1708 total_burst += nb_burst; 1709 if (nb_burst > burst_stats[0]) { 1710 burst_stats[1] = burst_stats[0]; 1711 pktnb_stats[1] = pktnb_stats[0]; 1712 burst_stats[0] = nb_burst; 1713 pktnb_stats[0] = nb_pkt; 1714 } else if (nb_burst > burst_stats[1]) { 1715 burst_stats[1] = nb_burst; 1716 pktnb_stats[1] = nb_pkt; 1717 } 1718 } 1719 if (total_burst == 0) 1720 return; 1721 burst_percent[0] = (burst_stats[0] * 100) / total_burst; 1722 printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst, 1723 burst_percent[0], (int) pktnb_stats[0]); 1724 if (burst_stats[0] == total_burst) { 1725 printf("]\n"); 1726 return; 1727 } 1728 if (burst_stats[0] + burst_stats[1] == total_burst) { 1729 printf(" + %d%% of %d pkts]\n", 1730 100 - burst_percent[0], pktnb_stats[1]); 1731 return; 1732 } 1733 burst_percent[1] = (burst_stats[1] * 100) / total_burst; 1734 burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]); 1735 if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) { 1736 printf(" + %d%% of others]\n", 100 - burst_percent[0]); 1737 return; 1738 } 1739 printf(" + %d%% of %d pkts + %d%% of others]\n", 1740 burst_percent[1], (int) pktnb_stats[1], burst_percent[2]); 1741 } 1742 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */ 1743 1744 static void 1745 fwd_stream_stats_display(streamid_t stream_id) 1746 { 1747 struct fwd_stream *fs; 1748 static const char *fwd_top_stats_border = "-------"; 1749 1750 fs = fwd_streams[stream_id]; 1751 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) && 1752 (fs->fwd_dropped == 0)) 1753 return; 1754 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> " 1755 "TX Port=%2d/Queue=%2d %s\n", 1756 fwd_top_stats_border, fs->rx_port, fs->rx_queue, 1757 fs->tx_port, fs->tx_queue, fwd_top_stats_border); 1758 printf(" RX-packets: %-14"PRIu64" TX-packets: %-14"PRIu64 1759 " TX-dropped: %-14"PRIu64, 1760 fs->rx_packets, fs->tx_packets, fs->fwd_dropped); 1761 1762 /* if checksum mode */ 1763 if (cur_fwd_eng == &csum_fwd_engine) { 1764 printf(" RX- bad IP checksum: %-14"PRIu64 1765 " Rx- bad L4 checksum: %-14"PRIu64 1766 " Rx- bad outer L4 checksum: %-14"PRIu64"\n", 1767 fs->rx_bad_ip_csum, fs->rx_bad_l4_csum, 1768 fs->rx_bad_outer_l4_csum); 1769 } else { 1770 printf("\n"); 1771 } 1772 1773 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1774 pkt_burst_stats_display("RX", &fs->rx_burst_stats); 1775 pkt_burst_stats_display("TX", &fs->tx_burst_stats); 1776 #endif 1777 } 1778 1779 void 1780 fwd_stats_display(void) 1781 { 1782 static const char *fwd_stats_border = "----------------------"; 1783 static const char *acc_stats_border = "+++++++++++++++"; 1784 struct { 1785 struct fwd_stream *rx_stream; 1786 struct fwd_stream *tx_stream; 1787 uint64_t tx_dropped; 1788 uint64_t rx_bad_ip_csum; 1789 uint64_t rx_bad_l4_csum; 1790 uint64_t rx_bad_outer_l4_csum; 1791 } ports_stats[RTE_MAX_ETHPORTS]; 1792 uint64_t total_rx_dropped = 0; 1793 uint64_t total_tx_dropped = 0; 1794 uint64_t total_rx_nombuf = 0; 1795 struct rte_eth_stats stats; 1796 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1797 uint64_t fwd_cycles = 0; 1798 #endif 1799 uint64_t total_recv = 0; 1800 uint64_t total_xmit = 0; 1801 struct rte_port *port; 1802 streamid_t sm_id; 1803 portid_t pt_id; 1804 int i; 1805 1806 memset(ports_stats, 0, sizeof(ports_stats)); 1807 1808 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1809 struct fwd_stream *fs = fwd_streams[sm_id]; 1810 1811 if (cur_fwd_config.nb_fwd_streams > 1812 cur_fwd_config.nb_fwd_ports) { 1813 fwd_stream_stats_display(sm_id); 1814 } else { 1815 ports_stats[fs->tx_port].tx_stream = fs; 1816 ports_stats[fs->rx_port].rx_stream = fs; 1817 } 1818 1819 ports_stats[fs->tx_port].tx_dropped += fs->fwd_dropped; 1820 1821 ports_stats[fs->rx_port].rx_bad_ip_csum += fs->rx_bad_ip_csum; 1822 ports_stats[fs->rx_port].rx_bad_l4_csum += fs->rx_bad_l4_csum; 1823 ports_stats[fs->rx_port].rx_bad_outer_l4_csum += 1824 fs->rx_bad_outer_l4_csum; 1825 1826 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1827 fwd_cycles += fs->core_cycles; 1828 #endif 1829 } 1830 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1831 uint8_t j; 1832 1833 pt_id = fwd_ports_ids[i]; 1834 port = &ports[pt_id]; 1835 1836 rte_eth_stats_get(pt_id, &stats); 1837 stats.ipackets -= port->stats.ipackets; 1838 stats.opackets -= port->stats.opackets; 1839 stats.ibytes -= port->stats.ibytes; 1840 stats.obytes -= port->stats.obytes; 1841 stats.imissed -= port->stats.imissed; 1842 stats.oerrors -= port->stats.oerrors; 1843 stats.rx_nombuf -= port->stats.rx_nombuf; 1844 1845 total_recv += stats.ipackets; 1846 total_xmit += stats.opackets; 1847 total_rx_dropped += stats.imissed; 1848 total_tx_dropped += ports_stats[pt_id].tx_dropped; 1849 total_tx_dropped += stats.oerrors; 1850 total_rx_nombuf += stats.rx_nombuf; 1851 1852 printf("\n %s Forward statistics for port %-2d %s\n", 1853 fwd_stats_border, pt_id, fwd_stats_border); 1854 1855 if (!port->rx_queue_stats_mapping_enabled && 1856 !port->tx_queue_stats_mapping_enabled) { 1857 printf(" RX-packets: %-14"PRIu64 1858 " RX-dropped: %-14"PRIu64 1859 "RX-total: %-"PRIu64"\n", 1860 stats.ipackets, stats.imissed, 1861 stats.ipackets + stats.imissed); 1862 1863 if (cur_fwd_eng == &csum_fwd_engine) 1864 printf(" Bad-ipcsum: %-14"PRIu64 1865 " Bad-l4csum: %-14"PRIu64 1866 "Bad-outer-l4csum: %-14"PRIu64"\n", 1867 ports_stats[pt_id].rx_bad_ip_csum, 1868 ports_stats[pt_id].rx_bad_l4_csum, 1869 ports_stats[pt_id].rx_bad_outer_l4_csum); 1870 if (stats.ierrors + stats.rx_nombuf > 0) { 1871 printf(" RX-error: %-"PRIu64"\n", 1872 stats.ierrors); 1873 printf(" RX-nombufs: %-14"PRIu64"\n", 1874 stats.rx_nombuf); 1875 } 1876 1877 printf(" TX-packets: %-14"PRIu64 1878 " TX-dropped: %-14"PRIu64 1879 "TX-total: %-"PRIu64"\n", 1880 stats.opackets, ports_stats[pt_id].tx_dropped, 1881 stats.opackets + ports_stats[pt_id].tx_dropped); 1882 } else { 1883 printf(" RX-packets: %14"PRIu64 1884 " RX-dropped:%14"PRIu64 1885 " RX-total:%14"PRIu64"\n", 1886 stats.ipackets, stats.imissed, 1887 stats.ipackets + stats.imissed); 1888 1889 if (cur_fwd_eng == &csum_fwd_engine) 1890 printf(" Bad-ipcsum:%14"PRIu64 1891 " Bad-l4csum:%14"PRIu64 1892 " Bad-outer-l4csum: %-14"PRIu64"\n", 1893 ports_stats[pt_id].rx_bad_ip_csum, 1894 ports_stats[pt_id].rx_bad_l4_csum, 1895 ports_stats[pt_id].rx_bad_outer_l4_csum); 1896 if ((stats.ierrors + stats.rx_nombuf) > 0) { 1897 printf(" RX-error:%"PRIu64"\n", stats.ierrors); 1898 printf(" RX-nombufs: %14"PRIu64"\n", 1899 stats.rx_nombuf); 1900 } 1901 1902 printf(" TX-packets: %14"PRIu64 1903 " TX-dropped:%14"PRIu64 1904 " TX-total:%14"PRIu64"\n", 1905 stats.opackets, ports_stats[pt_id].tx_dropped, 1906 stats.opackets + ports_stats[pt_id].tx_dropped); 1907 } 1908 1909 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1910 if (ports_stats[pt_id].rx_stream) 1911 pkt_burst_stats_display("RX", 1912 &ports_stats[pt_id].rx_stream->rx_burst_stats); 1913 if (ports_stats[pt_id].tx_stream) 1914 pkt_burst_stats_display("TX", 1915 &ports_stats[pt_id].tx_stream->tx_burst_stats); 1916 #endif 1917 1918 if (port->rx_queue_stats_mapping_enabled) { 1919 printf("\n"); 1920 for (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) { 1921 printf(" Stats reg %2d RX-packets:%14"PRIu64 1922 " RX-errors:%14"PRIu64 1923 " RX-bytes:%14"PRIu64"\n", 1924 j, stats.q_ipackets[j], 1925 stats.q_errors[j], stats.q_ibytes[j]); 1926 } 1927 printf("\n"); 1928 } 1929 if (port->tx_queue_stats_mapping_enabled) { 1930 for (j = 0; j < RTE_ETHDEV_QUEUE_STAT_CNTRS; j++) { 1931 printf(" Stats reg %2d TX-packets:%14"PRIu64 1932 " TX-bytes:%14" 1933 PRIu64"\n", 1934 j, stats.q_opackets[j], 1935 stats.q_obytes[j]); 1936 } 1937 } 1938 1939 printf(" %s--------------------------------%s\n", 1940 fwd_stats_border, fwd_stats_border); 1941 } 1942 1943 printf("\n %s Accumulated forward statistics for all ports" 1944 "%s\n", 1945 acc_stats_border, acc_stats_border); 1946 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: " 1947 "%-"PRIu64"\n" 1948 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: " 1949 "%-"PRIu64"\n", 1950 total_recv, total_rx_dropped, total_recv + total_rx_dropped, 1951 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped); 1952 if (total_rx_nombuf > 0) 1953 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf); 1954 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++" 1955 "%s\n", 1956 acc_stats_border, acc_stats_border); 1957 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1958 if (total_recv > 0) 1959 printf("\n CPU cycles/packet=%u (total cycles=" 1960 "%"PRIu64" / total RX packets=%"PRIu64")\n", 1961 (unsigned int)(fwd_cycles / total_recv), 1962 fwd_cycles, total_recv); 1963 #endif 1964 } 1965 1966 void 1967 fwd_stats_reset(void) 1968 { 1969 streamid_t sm_id; 1970 portid_t pt_id; 1971 int i; 1972 1973 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 1974 pt_id = fwd_ports_ids[i]; 1975 rte_eth_stats_get(pt_id, &ports[pt_id].stats); 1976 } 1977 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) { 1978 struct fwd_stream *fs = fwd_streams[sm_id]; 1979 1980 fs->rx_packets = 0; 1981 fs->tx_packets = 0; 1982 fs->fwd_dropped = 0; 1983 fs->rx_bad_ip_csum = 0; 1984 fs->rx_bad_l4_csum = 0; 1985 fs->rx_bad_outer_l4_csum = 0; 1986 1987 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS 1988 memset(&fs->rx_burst_stats, 0, sizeof(fs->rx_burst_stats)); 1989 memset(&fs->tx_burst_stats, 0, sizeof(fs->tx_burst_stats)); 1990 #endif 1991 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES 1992 fs->core_cycles = 0; 1993 #endif 1994 } 1995 } 1996 1997 static void 1998 flush_fwd_rx_queues(void) 1999 { 2000 struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; 2001 portid_t rxp; 2002 portid_t port_id; 2003 queueid_t rxq; 2004 uint16_t nb_rx; 2005 uint16_t i; 2006 uint8_t j; 2007 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; 2008 uint64_t timer_period; 2009 2010 /* convert to number of cycles */ 2011 timer_period = rte_get_timer_hz(); /* 1 second timeout */ 2012 2013 for (j = 0; j < 2; j++) { 2014 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { 2015 for (rxq = 0; rxq < nb_rxq; rxq++) { 2016 port_id = fwd_ports_ids[rxp]; 2017 /** 2018 * testpmd can stuck in the below do while loop 2019 * if rte_eth_rx_burst() always returns nonzero 2020 * packets. So timer is added to exit this loop 2021 * after 1sec timer expiry. 2022 */ 2023 prev_tsc = rte_rdtsc(); 2024 do { 2025 nb_rx = rte_eth_rx_burst(port_id, rxq, 2026 pkts_burst, MAX_PKT_BURST); 2027 for (i = 0; i < nb_rx; i++) 2028 rte_pktmbuf_free(pkts_burst[i]); 2029 2030 cur_tsc = rte_rdtsc(); 2031 diff_tsc = cur_tsc - prev_tsc; 2032 timer_tsc += diff_tsc; 2033 } while ((nb_rx > 0) && 2034 (timer_tsc < timer_period)); 2035 timer_tsc = 0; 2036 } 2037 } 2038 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ 2039 } 2040 } 2041 2042 static void 2043 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd) 2044 { 2045 struct fwd_stream **fsm; 2046 streamid_t nb_fs; 2047 streamid_t sm_id; 2048 #ifdef RTE_LIBRTE_BITRATE 2049 uint64_t tics_per_1sec; 2050 uint64_t tics_datum; 2051 uint64_t tics_current; 2052 uint16_t i, cnt_ports; 2053 2054 cnt_ports = nb_ports; 2055 tics_datum = rte_rdtsc(); 2056 tics_per_1sec = rte_get_timer_hz(); 2057 #endif 2058 fsm = &fwd_streams[fc->stream_idx]; 2059 nb_fs = fc->stream_nb; 2060 do { 2061 for (sm_id = 0; sm_id < nb_fs; sm_id++) 2062 (*pkt_fwd)(fsm[sm_id]); 2063 #ifdef RTE_LIBRTE_BITRATE 2064 if (bitrate_enabled != 0 && 2065 bitrate_lcore_id == rte_lcore_id()) { 2066 tics_current = rte_rdtsc(); 2067 if (tics_current - tics_datum >= tics_per_1sec) { 2068 /* Periodic bitrate calculation */ 2069 for (i = 0; i < cnt_ports; i++) 2070 rte_stats_bitrate_calc(bitrate_data, 2071 ports_ids[i]); 2072 tics_datum = tics_current; 2073 } 2074 } 2075 #endif 2076 #ifdef RTE_LIBRTE_LATENCY_STATS 2077 if (latencystats_enabled != 0 && 2078 latencystats_lcore_id == rte_lcore_id()) 2079 rte_latencystats_update(); 2080 #endif 2081 2082 } while (! fc->stopped); 2083 } 2084 2085 static int 2086 start_pkt_forward_on_core(void *fwd_arg) 2087 { 2088 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg, 2089 cur_fwd_config.fwd_eng->packet_fwd); 2090 return 0; 2091 } 2092 2093 /* 2094 * Run the TXONLY packet forwarding engine to send a single burst of packets. 2095 * Used to start communication flows in network loopback test configurations. 2096 */ 2097 static int 2098 run_one_txonly_burst_on_core(void *fwd_arg) 2099 { 2100 struct fwd_lcore *fwd_lc; 2101 struct fwd_lcore tmp_lcore; 2102 2103 fwd_lc = (struct fwd_lcore *) fwd_arg; 2104 tmp_lcore = *fwd_lc; 2105 tmp_lcore.stopped = 1; 2106 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd); 2107 return 0; 2108 } 2109 2110 /* 2111 * Launch packet forwarding: 2112 * - Setup per-port forwarding context. 2113 * - launch logical cores with their forwarding configuration. 2114 */ 2115 static void 2116 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore) 2117 { 2118 port_fwd_begin_t port_fwd_begin; 2119 unsigned int i; 2120 unsigned int lc_id; 2121 int diag; 2122 2123 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin; 2124 if (port_fwd_begin != NULL) { 2125 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 2126 (*port_fwd_begin)(fwd_ports_ids[i]); 2127 } 2128 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) { 2129 lc_id = fwd_lcores_cpuids[i]; 2130 if ((interactive == 0) || (lc_id != rte_lcore_id())) { 2131 fwd_lcores[i]->stopped = 0; 2132 diag = rte_eal_remote_launch(pkt_fwd_on_lcore, 2133 fwd_lcores[i], lc_id); 2134 if (diag != 0) 2135 printf("launch lcore %u failed - diag=%d\n", 2136 lc_id, diag); 2137 } 2138 } 2139 } 2140 2141 /* 2142 * Launch packet forwarding configuration. 2143 */ 2144 void 2145 start_packet_forwarding(int with_tx_first) 2146 { 2147 port_fwd_begin_t port_fwd_begin; 2148 port_fwd_end_t port_fwd_end; 2149 struct rte_port *port; 2150 unsigned int i; 2151 portid_t pt_id; 2152 2153 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq) 2154 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n"); 2155 2156 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq) 2157 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n"); 2158 2159 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 && 2160 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) && 2161 (!nb_rxq || !nb_txq)) 2162 rte_exit(EXIT_FAILURE, 2163 "Either rxq or txq are 0, cannot use %s fwd mode\n", 2164 cur_fwd_eng->fwd_mode_name); 2165 2166 if (all_ports_started() == 0) { 2167 printf("Not all ports were started\n"); 2168 return; 2169 } 2170 if (test_done == 0) { 2171 printf("Packet forwarding already started\n"); 2172 return; 2173 } 2174 2175 2176 if(dcb_test) { 2177 for (i = 0; i < nb_fwd_ports; i++) { 2178 pt_id = fwd_ports_ids[i]; 2179 port = &ports[pt_id]; 2180 if (!port->dcb_flag) { 2181 printf("In DCB mode, all forwarding ports must " 2182 "be configured in this mode.\n"); 2183 return; 2184 } 2185 } 2186 if (nb_fwd_lcores == 1) { 2187 printf("In DCB mode,the nb forwarding cores " 2188 "should be larger than 1.\n"); 2189 return; 2190 } 2191 } 2192 test_done = 0; 2193 2194 fwd_config_setup(); 2195 2196 if(!no_flush_rx) 2197 flush_fwd_rx_queues(); 2198 2199 pkt_fwd_config_display(&cur_fwd_config); 2200 rxtx_config_display(); 2201 2202 fwd_stats_reset(); 2203 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 2204 pt_id = fwd_ports_ids[i]; 2205 port = &ports[pt_id]; 2206 map_port_queue_stats_mapping_registers(pt_id, port); 2207 } 2208 if (with_tx_first) { 2209 port_fwd_begin = tx_only_engine.port_fwd_begin; 2210 if (port_fwd_begin != NULL) { 2211 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 2212 (*port_fwd_begin)(fwd_ports_ids[i]); 2213 } 2214 while (with_tx_first--) { 2215 launch_packet_forwarding( 2216 run_one_txonly_burst_on_core); 2217 rte_eal_mp_wait_lcore(); 2218 } 2219 port_fwd_end = tx_only_engine.port_fwd_end; 2220 if (port_fwd_end != NULL) { 2221 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 2222 (*port_fwd_end)(fwd_ports_ids[i]); 2223 } 2224 } 2225 launch_packet_forwarding(start_pkt_forward_on_core); 2226 } 2227 2228 void 2229 stop_packet_forwarding(void) 2230 { 2231 port_fwd_end_t port_fwd_end; 2232 lcoreid_t lc_id; 2233 portid_t pt_id; 2234 int i; 2235 2236 if (test_done) { 2237 printf("Packet forwarding not started\n"); 2238 return; 2239 } 2240 printf("Telling cores to stop..."); 2241 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) 2242 fwd_lcores[lc_id]->stopped = 1; 2243 printf("\nWaiting for lcores to finish...\n"); 2244 rte_eal_mp_wait_lcore(); 2245 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end; 2246 if (port_fwd_end != NULL) { 2247 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { 2248 pt_id = fwd_ports_ids[i]; 2249 (*port_fwd_end)(pt_id); 2250 } 2251 } 2252 2253 fwd_stats_display(); 2254 2255 printf("\nDone.\n"); 2256 test_done = 1; 2257 } 2258 2259 void 2260 dev_set_link_up(portid_t pid) 2261 { 2262 if (rte_eth_dev_set_link_up(pid) < 0) 2263 printf("\nSet link up fail.\n"); 2264 } 2265 2266 void 2267 dev_set_link_down(portid_t pid) 2268 { 2269 if (rte_eth_dev_set_link_down(pid) < 0) 2270 printf("\nSet link down fail.\n"); 2271 } 2272 2273 static int 2274 all_ports_started(void) 2275 { 2276 portid_t pi; 2277 struct rte_port *port; 2278 2279 RTE_ETH_FOREACH_DEV(pi) { 2280 port = &ports[pi]; 2281 /* Check if there is a port which is not started */ 2282 if ((port->port_status != RTE_PORT_STARTED) && 2283 (port->slave_flag == 0)) 2284 return 0; 2285 } 2286 2287 /* No port is not started */ 2288 return 1; 2289 } 2290 2291 int 2292 port_is_stopped(portid_t port_id) 2293 { 2294 struct rte_port *port = &ports[port_id]; 2295 2296 if ((port->port_status != RTE_PORT_STOPPED) && 2297 (port->slave_flag == 0)) 2298 return 0; 2299 return 1; 2300 } 2301 2302 int 2303 all_ports_stopped(void) 2304 { 2305 portid_t pi; 2306 2307 RTE_ETH_FOREACH_DEV(pi) { 2308 if (!port_is_stopped(pi)) 2309 return 0; 2310 } 2311 2312 return 1; 2313 } 2314 2315 int 2316 port_is_started(portid_t port_id) 2317 { 2318 if (port_id_is_invalid(port_id, ENABLED_WARN)) 2319 return 0; 2320 2321 if (ports[port_id].port_status != RTE_PORT_STARTED) 2322 return 0; 2323 2324 return 1; 2325 } 2326 2327 /* Configure the Rx and Tx hairpin queues for the selected port. */ 2328 static int 2329 setup_hairpin_queues(portid_t pi) 2330 { 2331 queueid_t qi; 2332 struct rte_eth_hairpin_conf hairpin_conf = { 2333 .peer_count = 1, 2334 }; 2335 int i; 2336 int diag; 2337 struct rte_port *port = &ports[pi]; 2338 2339 for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) { 2340 hairpin_conf.peers[0].port = pi; 2341 hairpin_conf.peers[0].queue = i + nb_rxq; 2342 diag = rte_eth_tx_hairpin_queue_setup 2343 (pi, qi, nb_txd, &hairpin_conf); 2344 i++; 2345 if (diag == 0) 2346 continue; 2347 2348 /* Fail to setup rx queue, return */ 2349 if (rte_atomic16_cmpset(&(port->port_status), 2350 RTE_PORT_HANDLING, 2351 RTE_PORT_STOPPED) == 0) 2352 printf("Port %d can not be set back " 2353 "to stopped\n", pi); 2354 printf("Fail to configure port %d hairpin " 2355 "queues\n", pi); 2356 /* try to reconfigure queues next time */ 2357 port->need_reconfig_queues = 1; 2358 return -1; 2359 } 2360 for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) { 2361 hairpin_conf.peers[0].port = pi; 2362 hairpin_conf.peers[0].queue = i + nb_txq; 2363 diag = rte_eth_rx_hairpin_queue_setup 2364 (pi, qi, nb_rxd, &hairpin_conf); 2365 i++; 2366 if (diag == 0) 2367 continue; 2368 2369 /* Fail to setup rx queue, return */ 2370 if (rte_atomic16_cmpset(&(port->port_status), 2371 RTE_PORT_HANDLING, 2372 RTE_PORT_STOPPED) == 0) 2373 printf("Port %d can not be set back " 2374 "to stopped\n", pi); 2375 printf("Fail to configure port %d hairpin " 2376 "queues\n", pi); 2377 /* try to reconfigure queues next time */ 2378 port->need_reconfig_queues = 1; 2379 return -1; 2380 } 2381 return 0; 2382 } 2383 2384 int 2385 start_port(portid_t pid) 2386 { 2387 int diag, need_check_link_status = -1; 2388 portid_t pi; 2389 queueid_t qi; 2390 struct rte_port *port; 2391 struct rte_ether_addr mac_addr; 2392 struct rte_eth_hairpin_cap cap; 2393 2394 if (port_id_is_invalid(pid, ENABLED_WARN)) 2395 return 0; 2396 2397 if(dcb_config) 2398 dcb_test = 1; 2399 RTE_ETH_FOREACH_DEV(pi) { 2400 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 2401 continue; 2402 2403 need_check_link_status = 0; 2404 port = &ports[pi]; 2405 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, 2406 RTE_PORT_HANDLING) == 0) { 2407 printf("Port %d is now not stopped\n", pi); 2408 continue; 2409 } 2410 2411 if (port->need_reconfig > 0) { 2412 port->need_reconfig = 0; 2413 2414 if (flow_isolate_all) { 2415 int ret = port_flow_isolate(pi, 1); 2416 if (ret) { 2417 printf("Failed to apply isolated" 2418 " mode on port %d\n", pi); 2419 return -1; 2420 } 2421 } 2422 configure_rxtx_dump_callbacks(0); 2423 printf("Configuring Port %d (socket %u)\n", pi, 2424 port->socket_id); 2425 if (nb_hairpinq > 0 && 2426 rte_eth_dev_hairpin_capability_get(pi, &cap)) { 2427 printf("Port %d doesn't support hairpin " 2428 "queues\n", pi); 2429 return -1; 2430 } 2431 /* configure port */ 2432 diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq, 2433 nb_txq + nb_hairpinq, 2434 &(port->dev_conf)); 2435 if (diag != 0) { 2436 if (rte_atomic16_cmpset(&(port->port_status), 2437 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 2438 printf("Port %d can not be set back " 2439 "to stopped\n", pi); 2440 printf("Fail to configure port %d\n", pi); 2441 /* try to reconfigure port next time */ 2442 port->need_reconfig = 1; 2443 return -1; 2444 } 2445 } 2446 if (port->need_reconfig_queues > 0) { 2447 port->need_reconfig_queues = 0; 2448 /* setup tx queues */ 2449 for (qi = 0; qi < nb_txq; qi++) { 2450 if ((numa_support) && 2451 (txring_numa[pi] != NUMA_NO_CONFIG)) 2452 diag = rte_eth_tx_queue_setup(pi, qi, 2453 port->nb_tx_desc[qi], 2454 txring_numa[pi], 2455 &(port->tx_conf[qi])); 2456 else 2457 diag = rte_eth_tx_queue_setup(pi, qi, 2458 port->nb_tx_desc[qi], 2459 port->socket_id, 2460 &(port->tx_conf[qi])); 2461 2462 if (diag == 0) 2463 continue; 2464 2465 /* Fail to setup tx queue, return */ 2466 if (rte_atomic16_cmpset(&(port->port_status), 2467 RTE_PORT_HANDLING, 2468 RTE_PORT_STOPPED) == 0) 2469 printf("Port %d can not be set back " 2470 "to stopped\n", pi); 2471 printf("Fail to configure port %d tx queues\n", 2472 pi); 2473 /* try to reconfigure queues next time */ 2474 port->need_reconfig_queues = 1; 2475 return -1; 2476 } 2477 for (qi = 0; qi < nb_rxq; qi++) { 2478 /* setup rx queues */ 2479 if ((numa_support) && 2480 (rxring_numa[pi] != NUMA_NO_CONFIG)) { 2481 struct rte_mempool * mp = 2482 mbuf_pool_find(rxring_numa[pi]); 2483 if (mp == NULL) { 2484 printf("Failed to setup RX queue:" 2485 "No mempool allocation" 2486 " on the socket %d\n", 2487 rxring_numa[pi]); 2488 return -1; 2489 } 2490 2491 diag = rte_eth_rx_queue_setup(pi, qi, 2492 port->nb_rx_desc[qi], 2493 rxring_numa[pi], 2494 &(port->rx_conf[qi]), 2495 mp); 2496 } else { 2497 struct rte_mempool *mp = 2498 mbuf_pool_find(port->socket_id); 2499 if (mp == NULL) { 2500 printf("Failed to setup RX queue:" 2501 "No mempool allocation" 2502 " on the socket %d\n", 2503 port->socket_id); 2504 return -1; 2505 } 2506 diag = rte_eth_rx_queue_setup(pi, qi, 2507 port->nb_rx_desc[qi], 2508 port->socket_id, 2509 &(port->rx_conf[qi]), 2510 mp); 2511 } 2512 if (diag == 0) 2513 continue; 2514 2515 /* Fail to setup rx queue, return */ 2516 if (rte_atomic16_cmpset(&(port->port_status), 2517 RTE_PORT_HANDLING, 2518 RTE_PORT_STOPPED) == 0) 2519 printf("Port %d can not be set back " 2520 "to stopped\n", pi); 2521 printf("Fail to configure port %d rx queues\n", 2522 pi); 2523 /* try to reconfigure queues next time */ 2524 port->need_reconfig_queues = 1; 2525 return -1; 2526 } 2527 /* setup hairpin queues */ 2528 if (setup_hairpin_queues(pi) != 0) 2529 return -1; 2530 } 2531 configure_rxtx_dump_callbacks(verbose_level); 2532 if (clear_ptypes) { 2533 diag = rte_eth_dev_set_ptypes(pi, RTE_PTYPE_UNKNOWN, 2534 NULL, 0); 2535 if (diag < 0) 2536 printf( 2537 "Port %d: Failed to disable Ptype parsing\n", 2538 pi); 2539 } 2540 2541 /* start port */ 2542 if (rte_eth_dev_start(pi) < 0) { 2543 printf("Fail to start port %d\n", pi); 2544 2545 /* Fail to setup rx queue, return */ 2546 if (rte_atomic16_cmpset(&(port->port_status), 2547 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 2548 printf("Port %d can not be set back to " 2549 "stopped\n", pi); 2550 continue; 2551 } 2552 2553 if (rte_atomic16_cmpset(&(port->port_status), 2554 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) 2555 printf("Port %d can not be set into started\n", pi); 2556 2557 if (eth_macaddr_get_print_err(pi, &mac_addr) == 0) 2558 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, 2559 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], 2560 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], 2561 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); 2562 2563 /* at least one port started, need checking link status */ 2564 need_check_link_status = 1; 2565 } 2566 2567 if (need_check_link_status == 1 && !no_link_check) 2568 check_all_ports_link_status(RTE_PORT_ALL); 2569 else if (need_check_link_status == 0) 2570 printf("Please stop the ports first\n"); 2571 2572 printf("Done\n"); 2573 return 0; 2574 } 2575 2576 void 2577 stop_port(portid_t pid) 2578 { 2579 portid_t pi; 2580 struct rte_port *port; 2581 int need_check_link_status = 0; 2582 2583 if (dcb_test) { 2584 dcb_test = 0; 2585 dcb_config = 0; 2586 } 2587 2588 if (port_id_is_invalid(pid, ENABLED_WARN)) 2589 return; 2590 2591 printf("Stopping ports...\n"); 2592 2593 RTE_ETH_FOREACH_DEV(pi) { 2594 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 2595 continue; 2596 2597 if (port_is_forwarding(pi) != 0 && test_done == 0) { 2598 printf("Please remove port %d from forwarding configuration.\n", pi); 2599 continue; 2600 } 2601 2602 if (port_is_bonding_slave(pi)) { 2603 printf("Please remove port %d from bonded device.\n", pi); 2604 continue; 2605 } 2606 2607 port = &ports[pi]; 2608 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, 2609 RTE_PORT_HANDLING) == 0) 2610 continue; 2611 2612 rte_eth_dev_stop(pi); 2613 2614 if (rte_atomic16_cmpset(&(port->port_status), 2615 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) 2616 printf("Port %d can not be set into stopped\n", pi); 2617 need_check_link_status = 1; 2618 } 2619 if (need_check_link_status && !no_link_check) 2620 check_all_ports_link_status(RTE_PORT_ALL); 2621 2622 printf("Done\n"); 2623 } 2624 2625 static void 2626 remove_invalid_ports_in(portid_t *array, portid_t *total) 2627 { 2628 portid_t i; 2629 portid_t new_total = 0; 2630 2631 for (i = 0; i < *total; i++) 2632 if (!port_id_is_invalid(array[i], DISABLED_WARN)) { 2633 array[new_total] = array[i]; 2634 new_total++; 2635 } 2636 *total = new_total; 2637 } 2638 2639 static void 2640 remove_invalid_ports(void) 2641 { 2642 remove_invalid_ports_in(ports_ids, &nb_ports); 2643 remove_invalid_ports_in(fwd_ports_ids, &nb_fwd_ports); 2644 nb_cfg_ports = nb_fwd_ports; 2645 } 2646 2647 void 2648 close_port(portid_t pid) 2649 { 2650 portid_t pi; 2651 struct rte_port *port; 2652 2653 if (port_id_is_invalid(pid, ENABLED_WARN)) 2654 return; 2655 2656 printf("Closing ports...\n"); 2657 2658 RTE_ETH_FOREACH_DEV(pi) { 2659 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 2660 continue; 2661 2662 if (port_is_forwarding(pi) != 0 && test_done == 0) { 2663 printf("Please remove port %d from forwarding configuration.\n", pi); 2664 continue; 2665 } 2666 2667 if (port_is_bonding_slave(pi)) { 2668 printf("Please remove port %d from bonded device.\n", pi); 2669 continue; 2670 } 2671 2672 port = &ports[pi]; 2673 if (rte_atomic16_cmpset(&(port->port_status), 2674 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { 2675 printf("Port %d is already closed\n", pi); 2676 continue; 2677 } 2678 2679 if (rte_atomic16_cmpset(&(port->port_status), 2680 RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { 2681 printf("Port %d is now not stopped\n", pi); 2682 continue; 2683 } 2684 2685 if (port->flow_list) 2686 port_flow_flush(pi); 2687 rte_eth_dev_close(pi); 2688 2689 remove_invalid_ports(); 2690 2691 if (rte_atomic16_cmpset(&(port->port_status), 2692 RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) 2693 printf("Port %d cannot be set to closed\n", pi); 2694 } 2695 2696 printf("Done\n"); 2697 } 2698 2699 void 2700 reset_port(portid_t pid) 2701 { 2702 int diag; 2703 portid_t pi; 2704 struct rte_port *port; 2705 2706 if (port_id_is_invalid(pid, ENABLED_WARN)) 2707 return; 2708 2709 if ((pid == (portid_t)RTE_PORT_ALL && !all_ports_stopped()) || 2710 (pid != (portid_t)RTE_PORT_ALL && !port_is_stopped(pid))) { 2711 printf("Can not reset port(s), please stop port(s) first.\n"); 2712 return; 2713 } 2714 2715 printf("Resetting ports...\n"); 2716 2717 RTE_ETH_FOREACH_DEV(pi) { 2718 if (pid != pi && pid != (portid_t)RTE_PORT_ALL) 2719 continue; 2720 2721 if (port_is_forwarding(pi) != 0 && test_done == 0) { 2722 printf("Please remove port %d from forwarding " 2723 "configuration.\n", pi); 2724 continue; 2725 } 2726 2727 if (port_is_bonding_slave(pi)) { 2728 printf("Please remove port %d from bonded device.\n", 2729 pi); 2730 continue; 2731 } 2732 2733 diag = rte_eth_dev_reset(pi); 2734 if (diag == 0) { 2735 port = &ports[pi]; 2736 port->need_reconfig = 1; 2737 port->need_reconfig_queues = 1; 2738 } else { 2739 printf("Failed to reset port %d. diag=%d\n", pi, diag); 2740 } 2741 } 2742 2743 printf("Done\n"); 2744 } 2745 2746 void 2747 attach_port(char *identifier) 2748 { 2749 portid_t pi; 2750 struct rte_dev_iterator iterator; 2751 2752 printf("Attaching a new port...\n"); 2753 2754 if (identifier == NULL) { 2755 printf("Invalid parameters are specified\n"); 2756 return; 2757 } 2758 2759 if (rte_dev_probe(identifier) < 0) { 2760 TESTPMD_LOG(ERR, "Failed to attach port %s\n", identifier); 2761 return; 2762 } 2763 2764 /* first attach mode: event */ 2765 if (setup_on_probe_event) { 2766 /* new ports are detected on RTE_ETH_EVENT_NEW event */ 2767 for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++) 2768 if (ports[pi].port_status == RTE_PORT_HANDLING && 2769 ports[pi].need_setup != 0) 2770 setup_attached_port(pi); 2771 return; 2772 } 2773 2774 /* second attach mode: iterator */ 2775 RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator) { 2776 /* setup ports matching the devargs used for probing */ 2777 if (port_is_forwarding(pi)) 2778 continue; /* port was already attached before */ 2779 setup_attached_port(pi); 2780 } 2781 } 2782 2783 static void 2784 setup_attached_port(portid_t pi) 2785 { 2786 unsigned int socket_id; 2787 int ret; 2788 2789 socket_id = (unsigned)rte_eth_dev_socket_id(pi); 2790 /* if socket_id is invalid, set to the first available socket. */ 2791 if (check_socket_id(socket_id) < 0) 2792 socket_id = socket_ids[0]; 2793 reconfig(pi, socket_id); 2794 ret = rte_eth_promiscuous_enable(pi); 2795 if (ret != 0) 2796 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n", 2797 pi, rte_strerror(-ret)); 2798 2799 ports_ids[nb_ports++] = pi; 2800 fwd_ports_ids[nb_fwd_ports++] = pi; 2801 nb_cfg_ports = nb_fwd_ports; 2802 ports[pi].need_setup = 0; 2803 ports[pi].port_status = RTE_PORT_STOPPED; 2804 2805 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); 2806 printf("Done\n"); 2807 } 2808 2809 static void 2810 detach_device(struct rte_device *dev) 2811 { 2812 portid_t sibling; 2813 2814 if (dev == NULL) { 2815 printf("Device already removed\n"); 2816 return; 2817 } 2818 2819 printf("Removing a device...\n"); 2820 2821 if (rte_dev_remove(dev) < 0) { 2822 TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name); 2823 return; 2824 } 2825 RTE_ETH_FOREACH_DEV_OF(sibling, dev) { 2826 /* reset mapping between old ports and removed device */ 2827 rte_eth_devices[sibling].device = NULL; 2828 if (ports[sibling].port_status != RTE_PORT_CLOSED) { 2829 /* sibling ports are forced to be closed */ 2830 ports[sibling].port_status = RTE_PORT_CLOSED; 2831 printf("Port %u is closed\n", sibling); 2832 } 2833 } 2834 2835 remove_invalid_ports(); 2836 2837 printf("Device is detached\n"); 2838 printf("Now total ports is %d\n", nb_ports); 2839 printf("Done\n"); 2840 return; 2841 } 2842 2843 void 2844 detach_port_device(portid_t port_id) 2845 { 2846 if (port_id_is_invalid(port_id, ENABLED_WARN)) 2847 return; 2848 2849 if (ports[port_id].port_status != RTE_PORT_CLOSED) { 2850 if (ports[port_id].port_status != RTE_PORT_STOPPED) { 2851 printf("Port not stopped\n"); 2852 return; 2853 } 2854 printf("Port was not closed\n"); 2855 if (ports[port_id].flow_list) 2856 port_flow_flush(port_id); 2857 } 2858 2859 detach_device(rte_eth_devices[port_id].device); 2860 } 2861 2862 void 2863 detach_devargs(char *identifier) 2864 { 2865 struct rte_dev_iterator iterator; 2866 struct rte_devargs da; 2867 portid_t port_id; 2868 2869 printf("Removing a device...\n"); 2870 2871 memset(&da, 0, sizeof(da)); 2872 if (rte_devargs_parsef(&da, "%s", identifier)) { 2873 printf("cannot parse identifier\n"); 2874 if (da.args) 2875 free(da.args); 2876 return; 2877 } 2878 2879 RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) { 2880 if (ports[port_id].port_status != RTE_PORT_CLOSED) { 2881 if (ports[port_id].port_status != RTE_PORT_STOPPED) { 2882 printf("Port %u not stopped\n", port_id); 2883 rte_eth_iterator_cleanup(&iterator); 2884 return; 2885 } 2886 2887 /* sibling ports are forced to be closed */ 2888 if (ports[port_id].flow_list) 2889 port_flow_flush(port_id); 2890 ports[port_id].port_status = RTE_PORT_CLOSED; 2891 printf("Port %u is now closed\n", port_id); 2892 } 2893 } 2894 2895 if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) { 2896 TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n", 2897 da.name, da.bus->name); 2898 return; 2899 } 2900 2901 remove_invalid_ports(); 2902 2903 printf("Device %s is detached\n", identifier); 2904 printf("Now total ports is %d\n", nb_ports); 2905 printf("Done\n"); 2906 } 2907 2908 void 2909 pmd_test_exit(void) 2910 { 2911 portid_t pt_id; 2912 int ret; 2913 int i; 2914 2915 if (test_done == 0) 2916 stop_packet_forwarding(); 2917 2918 for (i = 0 ; i < RTE_MAX_NUMA_NODES ; i++) { 2919 if (mempools[i]) { 2920 if (mp_alloc_type == MP_ALLOC_ANON) 2921 rte_mempool_mem_iter(mempools[i], dma_unmap_cb, 2922 NULL); 2923 } 2924 } 2925 if (ports != NULL) { 2926 no_link_check = 1; 2927 RTE_ETH_FOREACH_DEV(pt_id) { 2928 printf("\nStopping port %d...\n", pt_id); 2929 fflush(stdout); 2930 stop_port(pt_id); 2931 } 2932 RTE_ETH_FOREACH_DEV(pt_id) { 2933 printf("\nShutting down port %d...\n", pt_id); 2934 fflush(stdout); 2935 close_port(pt_id); 2936 } 2937 } 2938 2939 if (hot_plug) { 2940 ret = rte_dev_event_monitor_stop(); 2941 if (ret) { 2942 RTE_LOG(ERR, EAL, 2943 "fail to stop device event monitor."); 2944 return; 2945 } 2946 2947 ret = rte_dev_event_callback_unregister(NULL, 2948 dev_event_callback, NULL); 2949 if (ret < 0) { 2950 RTE_LOG(ERR, EAL, 2951 "fail to unregister device event callback.\n"); 2952 return; 2953 } 2954 2955 ret = rte_dev_hotplug_handle_disable(); 2956 if (ret) { 2957 RTE_LOG(ERR, EAL, 2958 "fail to disable hotplug handling.\n"); 2959 return; 2960 } 2961 } 2962 for (i = 0 ; i < RTE_MAX_NUMA_NODES ; i++) { 2963 if (mempools[i]) 2964 rte_mempool_free(mempools[i]); 2965 } 2966 2967 printf("\nBye...\n"); 2968 } 2969 2970 typedef void (*cmd_func_t)(void); 2971 struct pmd_test_command { 2972 const char *cmd_name; 2973 cmd_func_t cmd_func; 2974 }; 2975 2976 /* Check the link status of all ports in up to 9s, and print them finally */ 2977 static void 2978 check_all_ports_link_status(uint32_t port_mask) 2979 { 2980 #define CHECK_INTERVAL 100 /* 100ms */ 2981 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 2982 portid_t portid; 2983 uint8_t count, all_ports_up, print_flag = 0; 2984 struct rte_eth_link link; 2985 int ret; 2986 2987 printf("Checking link statuses...\n"); 2988 fflush(stdout); 2989 for (count = 0; count <= MAX_CHECK_TIME; count++) { 2990 all_ports_up = 1; 2991 RTE_ETH_FOREACH_DEV(portid) { 2992 if ((port_mask & (1 << portid)) == 0) 2993 continue; 2994 memset(&link, 0, sizeof(link)); 2995 ret = rte_eth_link_get_nowait(portid, &link); 2996 if (ret < 0) { 2997 all_ports_up = 0; 2998 if (print_flag == 1) 2999 printf("Port %u link get failed: %s\n", 3000 portid, rte_strerror(-ret)); 3001 continue; 3002 } 3003 /* print link status if flag set */ 3004 if (print_flag == 1) { 3005 if (link.link_status) 3006 printf( 3007 "Port%d Link Up. speed %u Mbps- %s\n", 3008 portid, link.link_speed, 3009 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? 3010 ("full-duplex") : ("half-duplex\n")); 3011 else 3012 printf("Port %d Link Down\n", portid); 3013 continue; 3014 } 3015 /* clear all_ports_up flag if any link down */ 3016 if (link.link_status == ETH_LINK_DOWN) { 3017 all_ports_up = 0; 3018 break; 3019 } 3020 } 3021 /* after finally printing all link status, get out */ 3022 if (print_flag == 1) 3023 break; 3024 3025 if (all_ports_up == 0) { 3026 fflush(stdout); 3027 rte_delay_ms(CHECK_INTERVAL); 3028 } 3029 3030 /* set the print_flag if all ports up or timeout */ 3031 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 3032 print_flag = 1; 3033 } 3034 3035 if (lsc_interrupt) 3036 break; 3037 } 3038 } 3039 3040 /* 3041 * This callback is for remove a port for a device. It has limitation because 3042 * it is not for multiple port removal for a device. 3043 * TODO: the device detach invoke will plan to be removed from user side to 3044 * eal. And convert all PMDs to free port resources on ether device closing. 3045 */ 3046 static void 3047 rmv_port_callback(void *arg) 3048 { 3049 int need_to_start = 0; 3050 int org_no_link_check = no_link_check; 3051 portid_t port_id = (intptr_t)arg; 3052 struct rte_device *dev; 3053 3054 RTE_ETH_VALID_PORTID_OR_RET(port_id); 3055 3056 if (!test_done && port_is_forwarding(port_id)) { 3057 need_to_start = 1; 3058 stop_packet_forwarding(); 3059 } 3060 no_link_check = 1; 3061 stop_port(port_id); 3062 no_link_check = org_no_link_check; 3063 3064 /* Save rte_device pointer before closing ethdev port */ 3065 dev = rte_eth_devices[port_id].device; 3066 close_port(port_id); 3067 detach_device(dev); /* might be already removed or have more ports */ 3068 3069 if (need_to_start) 3070 start_packet_forwarding(0); 3071 } 3072 3073 /* This function is used by the interrupt thread */ 3074 static int 3075 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param, 3076 void *ret_param) 3077 { 3078 RTE_SET_USED(param); 3079 RTE_SET_USED(ret_param); 3080 3081 if (type >= RTE_ETH_EVENT_MAX) { 3082 fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n", 3083 port_id, __func__, type); 3084 fflush(stderr); 3085 } else if (event_print_mask & (UINT32_C(1) << type)) { 3086 printf("\nPort %" PRIu16 ": %s event\n", port_id, 3087 eth_event_desc[type]); 3088 fflush(stdout); 3089 } 3090 3091 switch (type) { 3092 case RTE_ETH_EVENT_NEW: 3093 ports[port_id].need_setup = 1; 3094 ports[port_id].port_status = RTE_PORT_HANDLING; 3095 break; 3096 case RTE_ETH_EVENT_INTR_RMV: 3097 if (port_id_is_invalid(port_id, DISABLED_WARN)) 3098 break; 3099 if (rte_eal_alarm_set(100000, 3100 rmv_port_callback, (void *)(intptr_t)port_id)) 3101 fprintf(stderr, "Could not set up deferred device removal\n"); 3102 break; 3103 default: 3104 break; 3105 } 3106 return 0; 3107 } 3108 3109 static int 3110 register_eth_event_callback(void) 3111 { 3112 int ret; 3113 enum rte_eth_event_type event; 3114 3115 for (event = RTE_ETH_EVENT_UNKNOWN; 3116 event < RTE_ETH_EVENT_MAX; event++) { 3117 ret = rte_eth_dev_callback_register(RTE_ETH_ALL, 3118 event, 3119 eth_event_callback, 3120 NULL); 3121 if (ret != 0) { 3122 TESTPMD_LOG(ERR, "Failed to register callback for " 3123 "%s event\n", eth_event_desc[event]); 3124 return -1; 3125 } 3126 } 3127 3128 return 0; 3129 } 3130 3131 /* This function is used by the interrupt thread */ 3132 static void 3133 dev_event_callback(const char *device_name, enum rte_dev_event_type type, 3134 __rte_unused void *arg) 3135 { 3136 uint16_t port_id; 3137 int ret; 3138 3139 if (type >= RTE_DEV_EVENT_MAX) { 3140 fprintf(stderr, "%s called upon invalid event %d\n", 3141 __func__, type); 3142 fflush(stderr); 3143 } 3144 3145 switch (type) { 3146 case RTE_DEV_EVENT_REMOVE: 3147 RTE_LOG(DEBUG, EAL, "The device: %s has been removed!\n", 3148 device_name); 3149 ret = rte_eth_dev_get_port_by_name(device_name, &port_id); 3150 if (ret) { 3151 RTE_LOG(ERR, EAL, "can not get port by device %s!\n", 3152 device_name); 3153 return; 3154 } 3155 /* 3156 * Because the user's callback is invoked in eal interrupt 3157 * callback, the interrupt callback need to be finished before 3158 * it can be unregistered when detaching device. So finish 3159 * callback soon and use a deferred removal to detach device 3160 * is need. It is a workaround, once the device detaching be 3161 * moved into the eal in the future, the deferred removal could 3162 * be deleted. 3163 */ 3164 if (rte_eal_alarm_set(100000, 3165 rmv_port_callback, (void *)(intptr_t)port_id)) 3166 RTE_LOG(ERR, EAL, 3167 "Could not set up deferred device removal\n"); 3168 break; 3169 case RTE_DEV_EVENT_ADD: 3170 RTE_LOG(ERR, EAL, "The device: %s has been added!\n", 3171 device_name); 3172 /* TODO: After finish kernel driver binding, 3173 * begin to attach port. 3174 */ 3175 break; 3176 default: 3177 break; 3178 } 3179 } 3180 3181 static int 3182 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 3183 { 3184 uint16_t i; 3185 int diag; 3186 uint8_t mapping_found = 0; 3187 3188 for (i = 0; i < nb_tx_queue_stats_mappings; i++) { 3189 if ((tx_queue_stats_mappings[i].port_id == port_id) && 3190 (tx_queue_stats_mappings[i].queue_id < nb_txq )) { 3191 diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id, 3192 tx_queue_stats_mappings[i].queue_id, 3193 tx_queue_stats_mappings[i].stats_counter_id); 3194 if (diag != 0) 3195 return diag; 3196 mapping_found = 1; 3197 } 3198 } 3199 if (mapping_found) 3200 port->tx_queue_stats_mapping_enabled = 1; 3201 return 0; 3202 } 3203 3204 static int 3205 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port) 3206 { 3207 uint16_t i; 3208 int diag; 3209 uint8_t mapping_found = 0; 3210 3211 for (i = 0; i < nb_rx_queue_stats_mappings; i++) { 3212 if ((rx_queue_stats_mappings[i].port_id == port_id) && 3213 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) { 3214 diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id, 3215 rx_queue_stats_mappings[i].queue_id, 3216 rx_queue_stats_mappings[i].stats_counter_id); 3217 if (diag != 0) 3218 return diag; 3219 mapping_found = 1; 3220 } 3221 } 3222 if (mapping_found) 3223 port->rx_queue_stats_mapping_enabled = 1; 3224 return 0; 3225 } 3226 3227 static void 3228 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port) 3229 { 3230 int diag = 0; 3231 3232 diag = set_tx_queue_stats_mapping_registers(pi, port); 3233 if (diag != 0) { 3234 if (diag == -ENOTSUP) { 3235 port->tx_queue_stats_mapping_enabled = 0; 3236 printf("TX queue stats mapping not supported port id=%d\n", pi); 3237 } 3238 else 3239 rte_exit(EXIT_FAILURE, 3240 "set_tx_queue_stats_mapping_registers " 3241 "failed for port id=%d diag=%d\n", 3242 pi, diag); 3243 } 3244 3245 diag = set_rx_queue_stats_mapping_registers(pi, port); 3246 if (diag != 0) { 3247 if (diag == -ENOTSUP) { 3248 port->rx_queue_stats_mapping_enabled = 0; 3249 printf("RX queue stats mapping not supported port id=%d\n", pi); 3250 } 3251 else 3252 rte_exit(EXIT_FAILURE, 3253 "set_rx_queue_stats_mapping_registers " 3254 "failed for port id=%d diag=%d\n", 3255 pi, diag); 3256 } 3257 } 3258 3259 static void 3260 rxtx_port_config(struct rte_port *port) 3261 { 3262 uint16_t qid; 3263 uint64_t offloads; 3264 3265 for (qid = 0; qid < nb_rxq; qid++) { 3266 offloads = port->rx_conf[qid].offloads; 3267 port->rx_conf[qid] = port->dev_info.default_rxconf; 3268 if (offloads != 0) 3269 port->rx_conf[qid].offloads = offloads; 3270 3271 /* Check if any Rx parameters have been passed */ 3272 if (rx_pthresh != RTE_PMD_PARAM_UNSET) 3273 port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh; 3274 3275 if (rx_hthresh != RTE_PMD_PARAM_UNSET) 3276 port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh; 3277 3278 if (rx_wthresh != RTE_PMD_PARAM_UNSET) 3279 port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh; 3280 3281 if (rx_free_thresh != RTE_PMD_PARAM_UNSET) 3282 port->rx_conf[qid].rx_free_thresh = rx_free_thresh; 3283 3284 if (rx_drop_en != RTE_PMD_PARAM_UNSET) 3285 port->rx_conf[qid].rx_drop_en = rx_drop_en; 3286 3287 port->nb_rx_desc[qid] = nb_rxd; 3288 } 3289 3290 for (qid = 0; qid < nb_txq; qid++) { 3291 offloads = port->tx_conf[qid].offloads; 3292 port->tx_conf[qid] = port->dev_info.default_txconf; 3293 if (offloads != 0) 3294 port->tx_conf[qid].offloads = offloads; 3295 3296 /* Check if any Tx parameters have been passed */ 3297 if (tx_pthresh != RTE_PMD_PARAM_UNSET) 3298 port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh; 3299 3300 if (tx_hthresh != RTE_PMD_PARAM_UNSET) 3301 port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh; 3302 3303 if (tx_wthresh != RTE_PMD_PARAM_UNSET) 3304 port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh; 3305 3306 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET) 3307 port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh; 3308 3309 if (tx_free_thresh != RTE_PMD_PARAM_UNSET) 3310 port->tx_conf[qid].tx_free_thresh = tx_free_thresh; 3311 3312 port->nb_tx_desc[qid] = nb_txd; 3313 } 3314 } 3315 3316 void 3317 init_port_config(void) 3318 { 3319 portid_t pid; 3320 struct rte_port *port; 3321 int ret; 3322 3323 RTE_ETH_FOREACH_DEV(pid) { 3324 port = &ports[pid]; 3325 port->dev_conf.fdir_conf = fdir_conf; 3326 3327 ret = eth_dev_info_get_print_err(pid, &port->dev_info); 3328 if (ret != 0) 3329 return; 3330 3331 if (nb_rxq > 1) { 3332 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 3333 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 3334 rss_hf & port->dev_info.flow_type_rss_offloads; 3335 } else { 3336 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; 3337 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; 3338 } 3339 3340 if (port->dcb_flag == 0) { 3341 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) 3342 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 3343 else 3344 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; 3345 } 3346 3347 rxtx_port_config(port); 3348 3349 ret = eth_macaddr_get_print_err(pid, &port->eth_addr); 3350 if (ret != 0) 3351 return; 3352 3353 map_port_queue_stats_mapping_registers(pid, port); 3354 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS 3355 rte_pmd_ixgbe_bypass_init(pid); 3356 #endif 3357 3358 if (lsc_interrupt && 3359 (rte_eth_devices[pid].data->dev_flags & 3360 RTE_ETH_DEV_INTR_LSC)) 3361 port->dev_conf.intr_conf.lsc = 1; 3362 if (rmv_interrupt && 3363 (rte_eth_devices[pid].data->dev_flags & 3364 RTE_ETH_DEV_INTR_RMV)) 3365 port->dev_conf.intr_conf.rmv = 1; 3366 } 3367 } 3368 3369 void set_port_slave_flag(portid_t slave_pid) 3370 { 3371 struct rte_port *port; 3372 3373 port = &ports[slave_pid]; 3374 port->slave_flag = 1; 3375 } 3376 3377 void clear_port_slave_flag(portid_t slave_pid) 3378 { 3379 struct rte_port *port; 3380 3381 port = &ports[slave_pid]; 3382 port->slave_flag = 0; 3383 } 3384 3385 uint8_t port_is_bonding_slave(portid_t slave_pid) 3386 { 3387 struct rte_port *port; 3388 3389 port = &ports[slave_pid]; 3390 if ((rte_eth_devices[slave_pid].data->dev_flags & 3391 RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1)) 3392 return 1; 3393 return 0; 3394 } 3395 3396 const uint16_t vlan_tags[] = { 3397 0, 1, 2, 3, 4, 5, 6, 7, 3398 8, 9, 10, 11, 12, 13, 14, 15, 3399 16, 17, 18, 19, 20, 21, 22, 23, 3400 24, 25, 26, 27, 28, 29, 30, 31 3401 }; 3402 3403 static int 3404 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf, 3405 enum dcb_mode_enable dcb_mode, 3406 enum rte_eth_nb_tcs num_tcs, 3407 uint8_t pfc_en) 3408 { 3409 uint8_t i; 3410 int32_t rc; 3411 struct rte_eth_rss_conf rss_conf; 3412 3413 /* 3414 * Builds up the correct configuration for dcb+vt based on the vlan tags array 3415 * given above, and the number of traffic classes available for use. 3416 */ 3417 if (dcb_mode == DCB_VT_ENABLED) { 3418 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf = 3419 ð_conf->rx_adv_conf.vmdq_dcb_conf; 3420 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf = 3421 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf; 3422 3423 /* VMDQ+DCB RX and TX configurations */ 3424 vmdq_rx_conf->enable_default_pool = 0; 3425 vmdq_rx_conf->default_pool = 0; 3426 vmdq_rx_conf->nb_queue_pools = 3427 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 3428 vmdq_tx_conf->nb_queue_pools = 3429 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS); 3430 3431 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools; 3432 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) { 3433 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i]; 3434 vmdq_rx_conf->pool_map[i].pools = 3435 1 << (i % vmdq_rx_conf->nb_queue_pools); 3436 } 3437 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 3438 vmdq_rx_conf->dcb_tc[i] = i % num_tcs; 3439 vmdq_tx_conf->dcb_tc[i] = i % num_tcs; 3440 } 3441 3442 /* set DCB mode of RX and TX of multiple queues */ 3443 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB; 3444 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB; 3445 } else { 3446 struct rte_eth_dcb_rx_conf *rx_conf = 3447 ð_conf->rx_adv_conf.dcb_rx_conf; 3448 struct rte_eth_dcb_tx_conf *tx_conf = 3449 ð_conf->tx_adv_conf.dcb_tx_conf; 3450 3451 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf); 3452 if (rc != 0) 3453 return rc; 3454 3455 rx_conf->nb_tcs = num_tcs; 3456 tx_conf->nb_tcs = num_tcs; 3457 3458 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { 3459 rx_conf->dcb_tc[i] = i % num_tcs; 3460 tx_conf->dcb_tc[i] = i % num_tcs; 3461 } 3462 3463 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; 3464 eth_conf->rx_adv_conf.rss_conf = rss_conf; 3465 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB; 3466 } 3467 3468 if (pfc_en) 3469 eth_conf->dcb_capability_en = 3470 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT; 3471 else 3472 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT; 3473 3474 return 0; 3475 } 3476 3477 int 3478 init_port_dcb_config(portid_t pid, 3479 enum dcb_mode_enable dcb_mode, 3480 enum rte_eth_nb_tcs num_tcs, 3481 uint8_t pfc_en) 3482 { 3483 struct rte_eth_conf port_conf; 3484 struct rte_port *rte_port; 3485 int retval; 3486 uint16_t i; 3487 3488 rte_port = &ports[pid]; 3489 3490 memset(&port_conf, 0, sizeof(struct rte_eth_conf)); 3491 /* Enter DCB configuration status */ 3492 dcb_config = 1; 3493 3494 port_conf.rxmode = rte_port->dev_conf.rxmode; 3495 port_conf.txmode = rte_port->dev_conf.txmode; 3496 3497 /*set configuration of DCB in vt mode and DCB in non-vt mode*/ 3498 retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en); 3499 if (retval < 0) 3500 return retval; 3501 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 3502 3503 /* re-configure the device . */ 3504 retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf); 3505 if (retval < 0) 3506 return retval; 3507 3508 retval = eth_dev_info_get_print_err(pid, &rte_port->dev_info); 3509 if (retval != 0) 3510 return retval; 3511 3512 /* If dev_info.vmdq_pool_base is greater than 0, 3513 * the queue id of vmdq pools is started after pf queues. 3514 */ 3515 if (dcb_mode == DCB_VT_ENABLED && 3516 rte_port->dev_info.vmdq_pool_base > 0) { 3517 printf("VMDQ_DCB multi-queue mode is nonsensical" 3518 " for port %d.", pid); 3519 return -1; 3520 } 3521 3522 /* Assume the ports in testpmd have the same dcb capability 3523 * and has the same number of rxq and txq in dcb mode 3524 */ 3525 if (dcb_mode == DCB_VT_ENABLED) { 3526 if (rte_port->dev_info.max_vfs > 0) { 3527 nb_rxq = rte_port->dev_info.nb_rx_queues; 3528 nb_txq = rte_port->dev_info.nb_tx_queues; 3529 } else { 3530 nb_rxq = rte_port->dev_info.max_rx_queues; 3531 nb_txq = rte_port->dev_info.max_tx_queues; 3532 } 3533 } else { 3534 /*if vt is disabled, use all pf queues */ 3535 if (rte_port->dev_info.vmdq_pool_base == 0) { 3536 nb_rxq = rte_port->dev_info.max_rx_queues; 3537 nb_txq = rte_port->dev_info.max_tx_queues; 3538 } else { 3539 nb_rxq = (queueid_t)num_tcs; 3540 nb_txq = (queueid_t)num_tcs; 3541 3542 } 3543 } 3544 rx_free_thresh = 64; 3545 3546 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); 3547 3548 rxtx_port_config(rte_port); 3549 /* VLAN filter */ 3550 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER; 3551 for (i = 0; i < RTE_DIM(vlan_tags); i++) 3552 rx_vft_set(pid, vlan_tags[i], 1); 3553 3554 retval = eth_macaddr_get_print_err(pid, &rte_port->eth_addr); 3555 if (retval != 0) 3556 return retval; 3557 3558 map_port_queue_stats_mapping_registers(pid, rte_port); 3559 3560 rte_port->dcb_flag = 1; 3561 3562 return 0; 3563 } 3564 3565 static void 3566 init_port(void) 3567 { 3568 /* Configuration of Ethernet ports. */ 3569 ports = rte_zmalloc("testpmd: ports", 3570 sizeof(struct rte_port) * RTE_MAX_ETHPORTS, 3571 RTE_CACHE_LINE_SIZE); 3572 if (ports == NULL) { 3573 rte_exit(EXIT_FAILURE, 3574 "rte_zmalloc(%d struct rte_port) failed\n", 3575 RTE_MAX_ETHPORTS); 3576 } 3577 3578 /* Initialize ports NUMA structures */ 3579 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 3580 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 3581 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS); 3582 } 3583 3584 static void 3585 force_quit(void) 3586 { 3587 pmd_test_exit(); 3588 prompt_exit(); 3589 } 3590 3591 static void 3592 print_stats(void) 3593 { 3594 uint8_t i; 3595 const char clr[] = { 27, '[', '2', 'J', '\0' }; 3596 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' }; 3597 3598 /* Clear screen and move to top left */ 3599 printf("%s%s", clr, top_left); 3600 3601 printf("\nPort statistics ===================================="); 3602 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) 3603 nic_stats_display(fwd_ports_ids[i]); 3604 3605 fflush(stdout); 3606 } 3607 3608 static void 3609 signal_handler(int signum) 3610 { 3611 if (signum == SIGINT || signum == SIGTERM) { 3612 printf("\nSignal %d received, preparing to exit...\n", 3613 signum); 3614 #ifdef RTE_LIBRTE_PDUMP 3615 /* uninitialize packet capture framework */ 3616 rte_pdump_uninit(); 3617 #endif 3618 #ifdef RTE_LIBRTE_LATENCY_STATS 3619 if (latencystats_enabled != 0) 3620 rte_latencystats_uninit(); 3621 #endif 3622 force_quit(); 3623 /* Set flag to indicate the force termination. */ 3624 f_quit = 1; 3625 /* exit with the expected status */ 3626 signal(signum, SIG_DFL); 3627 kill(getpid(), signum); 3628 } 3629 } 3630 3631 int 3632 main(int argc, char** argv) 3633 { 3634 int diag; 3635 portid_t port_id; 3636 uint16_t count; 3637 int ret; 3638 3639 signal(SIGINT, signal_handler); 3640 signal(SIGTERM, signal_handler); 3641 3642 testpmd_logtype = rte_log_register("testpmd"); 3643 if (testpmd_logtype < 0) 3644 rte_exit(EXIT_FAILURE, "Cannot register log type"); 3645 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG); 3646 3647 diag = rte_eal_init(argc, argv); 3648 if (diag < 0) 3649 rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n", 3650 rte_strerror(rte_errno)); 3651 3652 if (rte_eal_process_type() == RTE_PROC_SECONDARY) 3653 rte_exit(EXIT_FAILURE, 3654 "Secondary process type not supported.\n"); 3655 3656 ret = register_eth_event_callback(); 3657 if (ret != 0) 3658 rte_exit(EXIT_FAILURE, "Cannot register for ethdev events"); 3659 3660 #ifdef RTE_LIBRTE_PDUMP 3661 /* initialize packet capture framework */ 3662 rte_pdump_init(); 3663 #endif 3664 3665 count = 0; 3666 RTE_ETH_FOREACH_DEV(port_id) { 3667 ports_ids[count] = port_id; 3668 count++; 3669 } 3670 nb_ports = (portid_t) count; 3671 if (nb_ports == 0) 3672 TESTPMD_LOG(WARNING, "No probed ethernet devices\n"); 3673 3674 /* allocate port structures, and init them */ 3675 init_port(); 3676 3677 set_def_fwd_config(); 3678 if (nb_lcores == 0) 3679 rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n" 3680 "Check the core mask argument\n"); 3681 3682 /* Bitrate/latency stats disabled by default */ 3683 #ifdef RTE_LIBRTE_BITRATE 3684 bitrate_enabled = 0; 3685 #endif 3686 #ifdef RTE_LIBRTE_LATENCY_STATS 3687 latencystats_enabled = 0; 3688 #endif 3689 3690 /* on FreeBSD, mlockall() is disabled by default */ 3691 #ifdef RTE_EXEC_ENV_FREEBSD 3692 do_mlockall = 0; 3693 #else 3694 do_mlockall = 1; 3695 #endif 3696 3697 argc -= diag; 3698 argv += diag; 3699 if (argc > 1) 3700 launch_args_parse(argc, argv); 3701 3702 if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) { 3703 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n", 3704 strerror(errno)); 3705 } 3706 3707 if (tx_first && interactive) 3708 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on " 3709 "interactive mode.\n"); 3710 3711 if (tx_first && lsc_interrupt) { 3712 printf("Warning: lsc_interrupt needs to be off when " 3713 " using tx_first. Disabling.\n"); 3714 lsc_interrupt = 0; 3715 } 3716 3717 if (!nb_rxq && !nb_txq) 3718 printf("Warning: Either rx or tx queues should be non-zero\n"); 3719 3720 if (nb_rxq > 1 && nb_rxq > nb_txq) 3721 printf("Warning: nb_rxq=%d enables RSS configuration, " 3722 "but nb_txq=%d will prevent to fully test it.\n", 3723 nb_rxq, nb_txq); 3724 3725 init_config(); 3726 3727 if (hot_plug) { 3728 ret = rte_dev_hotplug_handle_enable(); 3729 if (ret) { 3730 RTE_LOG(ERR, EAL, 3731 "fail to enable hotplug handling."); 3732 return -1; 3733 } 3734 3735 ret = rte_dev_event_monitor_start(); 3736 if (ret) { 3737 RTE_LOG(ERR, EAL, 3738 "fail to start device event monitoring."); 3739 return -1; 3740 } 3741 3742 ret = rte_dev_event_callback_register(NULL, 3743 dev_event_callback, NULL); 3744 if (ret) { 3745 RTE_LOG(ERR, EAL, 3746 "fail to register device event callback\n"); 3747 return -1; 3748 } 3749 } 3750 3751 if (!no_device_start && start_port(RTE_PORT_ALL) != 0) 3752 rte_exit(EXIT_FAILURE, "Start ports failed\n"); 3753 3754 /* set all ports to promiscuous mode by default */ 3755 RTE_ETH_FOREACH_DEV(port_id) { 3756 ret = rte_eth_promiscuous_enable(port_id); 3757 if (ret != 0) 3758 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n", 3759 port_id, rte_strerror(-ret)); 3760 } 3761 3762 /* Init metrics library */ 3763 rte_metrics_init(rte_socket_id()); 3764 3765 #ifdef RTE_LIBRTE_LATENCY_STATS 3766 if (latencystats_enabled != 0) { 3767 int ret = rte_latencystats_init(1, NULL); 3768 if (ret) 3769 printf("Warning: latencystats init()" 3770 " returned error %d\n", ret); 3771 printf("Latencystats running on lcore %d\n", 3772 latencystats_lcore_id); 3773 } 3774 #endif 3775 3776 /* Setup bitrate stats */ 3777 #ifdef RTE_LIBRTE_BITRATE 3778 if (bitrate_enabled != 0) { 3779 bitrate_data = rte_stats_bitrate_create(); 3780 if (bitrate_data == NULL) 3781 rte_exit(EXIT_FAILURE, 3782 "Could not allocate bitrate data.\n"); 3783 rte_stats_bitrate_reg(bitrate_data); 3784 } 3785 #endif 3786 3787 #ifdef RTE_LIBRTE_CMDLINE 3788 if (strlen(cmdline_filename) != 0) 3789 cmdline_read_from_file(cmdline_filename); 3790 3791 if (interactive == 1) { 3792 if (auto_start) { 3793 printf("Start automatic packet forwarding\n"); 3794 start_packet_forwarding(0); 3795 } 3796 prompt(); 3797 pmd_test_exit(); 3798 } else 3799 #endif 3800 { 3801 char c; 3802 int rc; 3803 3804 f_quit = 0; 3805 3806 printf("No commandline core given, start packet forwarding\n"); 3807 start_packet_forwarding(tx_first); 3808 if (stats_period != 0) { 3809 uint64_t prev_time = 0, cur_time, diff_time = 0; 3810 uint64_t timer_period; 3811 3812 /* Convert to number of cycles */ 3813 timer_period = stats_period * rte_get_timer_hz(); 3814 3815 while (f_quit == 0) { 3816 cur_time = rte_get_timer_cycles(); 3817 diff_time += cur_time - prev_time; 3818 3819 if (diff_time >= timer_period) { 3820 print_stats(); 3821 /* Reset the timer */ 3822 diff_time = 0; 3823 } 3824 /* Sleep to avoid unnecessary checks */ 3825 prev_time = cur_time; 3826 sleep(1); 3827 } 3828 } 3829 3830 printf("Press enter to exit\n"); 3831 rc = read(0, &c, 1); 3832 pmd_test_exit(); 3833 if (rc < 0) 3834 return 1; 3835 } 3836 3837 ret = rte_eal_cleanup(); 3838 if (ret != 0) 3839 rte_exit(EXIT_FAILURE, 3840 "EAL cleanup failed: %s\n", strerror(-ret)); 3841 3842 return EXIT_SUCCESS; 3843 } 3844