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