1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2017 Intel Corporation
12 #ifndef RTE_EXEC_ENV_WINDOWS
15 #include <sys/types.h>
19 #include <sys/queue.h>
26 #include <rte_common.h>
27 #include <rte_errno.h>
28 #include <rte_byteorder.h>
30 #include <rte_debug.h>
31 #include <rte_cycles.h>
32 #include <rte_memory.h>
33 #include <rte_memcpy.h>
34 #include <rte_launch.h>
36 #include <rte_alarm.h>
37 #include <rte_per_lcore.h>
38 #include <rte_lcore.h>
39 #include <rte_atomic.h>
40 #include <rte_branch_prediction.h>
41 #include <rte_mempool.h>
42 #include <rte_malloc.h>
44 #include <rte_mbuf_pool_ops.h>
45 #include <rte_interrupts.h>
47 #include <rte_ether.h>
48 #include <rte_ethdev.h>
50 #include <rte_string_fns.h>
52 #include <rte_pmd_ixgbe.h>
55 #include <rte_pdump.h>
58 #include <rte_metrics.h>
59 #ifdef RTE_LIB_BITRATESTATS
60 #include <rte_bitrate.h>
62 #ifdef RTE_LIB_LATENCYSTATS
63 #include <rte_latencystats.h>
65 #ifdef RTE_EXEC_ENV_WINDOWS
72 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */
73 #define HUGE_FLAG (0x40000)
75 #define HUGE_FLAG MAP_HUGETLB
78 #ifndef MAP_HUGE_SHIFT
79 /* older kernels (or FreeBSD) will not have this define */
80 #define HUGE_SHIFT (26)
82 #define HUGE_SHIFT MAP_HUGE_SHIFT
85 #define EXTMEM_HEAP_NAME "extmem"
86 #define EXTBUF_ZONE_SIZE RTE_PGSIZE_2M
88 uint16_t verbose_level = 0; /**< Silent by default. */
89 int testpmd_logtype; /**< Log type for testpmd logs */
91 /* use main core for command line ? */
92 uint8_t interactive = 0;
93 uint8_t auto_start = 0;
95 char cmdline_filename[PATH_MAX] = {0};
98 * NUMA support configuration.
99 * When set, the NUMA support attempts to dispatch the allocation of the
100 * RX and TX memory rings, and of the DMA memory buffers (mbufs) for the
101 * probed ports among the CPU sockets 0 and 1.
102 * Otherwise, all memory is allocated from CPU socket 0.
104 uint8_t numa_support = 1; /**< numa enabled by default */
107 * In UMA mode,all memory is allocated from socket 0 if --socket-num is
110 uint8_t socket_num = UMA_NO_CONFIG;
113 * Select mempool allocation type:
114 * - native: use regular DPDK memory
115 * - anon: use regular DPDK memory to create mempool, but populate using
116 * anonymous memory (may not be IOVA-contiguous)
117 * - xmem: use externally allocated hugepage memory
119 uint8_t mp_alloc_type = MP_ALLOC_NATIVE;
122 * Store specified sockets on which memory pool to be used by ports
125 uint8_t port_numa[RTE_MAX_ETHPORTS];
128 * Store specified sockets on which RX ring to be used by ports
131 uint8_t rxring_numa[RTE_MAX_ETHPORTS];
134 * Store specified sockets on which TX ring to be used by ports
137 uint8_t txring_numa[RTE_MAX_ETHPORTS];
140 * Record the Ethernet address of peer target ports to which packets are
142 * Must be instantiated with the ethernet addresses of peer traffic generator
145 struct rte_ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
146 portid_t nb_peer_eth_addrs = 0;
149 * Probed Target Environment.
151 struct rte_port *ports; /**< For all probed ethernet ports. */
152 portid_t nb_ports; /**< Number of probed ethernet ports. */
153 struct fwd_lcore **fwd_lcores; /**< For all probed logical cores. */
154 lcoreid_t nb_lcores; /**< Number of probed logical cores. */
156 portid_t ports_ids[RTE_MAX_ETHPORTS]; /**< Store all port ids. */
159 * Test Forwarding Configuration.
160 * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
161 * nb_fwd_ports <= nb_cfg_ports <= nb_ports
163 lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
164 lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
165 portid_t nb_cfg_ports; /**< Number of configured ports. */
166 portid_t nb_fwd_ports; /**< Number of forwarding ports. */
168 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
169 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */
171 struct fwd_stream **fwd_streams; /**< For each RX queue of each port. */
172 streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */
175 * Forwarding engines.
177 struct fwd_engine * fwd_engines[] = {
187 &five_tuple_swap_fwd_engine,
188 #ifdef RTE_LIBRTE_IEEE1588
189 &ieee1588_fwd_engine,
194 struct rte_mempool *mempools[RTE_MAX_NUMA_NODES * MAX_SEGS_BUFFER_SPLIT];
195 uint16_t mempool_flags;
197 struct fwd_config cur_fwd_config;
198 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
199 uint32_t retry_enabled;
200 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
201 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
203 uint32_t mbuf_data_size_n = 1; /* Number of specified mbuf sizes. */
204 uint16_t mbuf_data_size[MAX_SEGS_BUFFER_SPLIT] = {
205 DEFAULT_MBUF_DATA_SIZE
206 }; /**< Mbuf data space size. */
207 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if
208 * specified on command-line. */
209 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
212 * In container, it cannot terminate the process which running with 'stats-period'
213 * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
218 * Configuration of packet segments used to scatter received packets
219 * if some of split features is configured.
221 uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT];
222 uint8_t rx_pkt_nb_segs; /**< Number of segments to split */
223 uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT];
224 uint8_t rx_pkt_nb_offs; /**< Number of specified offsets */
227 * Configuration of packet segments used by the "txonly" processing engine.
229 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
230 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
231 TXONLY_DEF_PACKET_LEN,
233 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
235 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
236 /**< Split policy for packets to TX. */
238 uint8_t txonly_multi_flow;
239 /**< Whether multiple flows are generated in TXONLY mode. */
241 uint32_t tx_pkt_times_inter;
242 /**< Timings for send scheduling in TXONLY mode, time between bursts. */
244 uint32_t tx_pkt_times_intra;
245 /**< Timings for send scheduling in TXONLY mode, time between packets. */
247 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
248 uint16_t nb_pkt_flowgen_clones; /**< Number of Tx packet clones to send in flowgen mode. */
249 int nb_flows_flowgen = 1024; /**< Number of flows in flowgen mode. */
250 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
252 /* current configuration is in DCB or not,0 means it is not in DCB mode */
253 uint8_t dcb_config = 0;
256 * Configurable number of RX/TX queues.
258 queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */
259 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
260 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
263 * Configurable number of RX/TX ring descriptors.
264 * Defaults are supplied by drivers via ethdev.
266 #define RTE_TEST_RX_DESC_DEFAULT 0
267 #define RTE_TEST_TX_DESC_DEFAULT 0
268 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
269 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
271 #define RTE_PMD_PARAM_UNSET -1
273 * Configurable values of RX and TX ring threshold registers.
276 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
277 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
278 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
280 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
281 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
282 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
285 * Configurable value of RX free threshold.
287 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
290 * Configurable value of RX drop enable.
292 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
295 * Configurable value of TX free threshold.
297 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
300 * Configurable value of TX RS bit threshold.
302 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
305 * Configurable value of buffered packets before sending.
307 uint16_t noisy_tx_sw_bufsz;
310 * Configurable value of packet buffer timeout.
312 uint16_t noisy_tx_sw_buf_flush_time;
315 * Configurable value for size of VNF internal memory area
316 * used for simulating noisy neighbour behaviour
318 uint64_t noisy_lkup_mem_sz;
321 * Configurable value of number of random writes done in
322 * VNF simulation memory area.
324 uint64_t noisy_lkup_num_writes;
327 * Configurable value of number of random reads done in
328 * VNF simulation memory area.
330 uint64_t noisy_lkup_num_reads;
333 * Configurable value of number of random reads/writes done in
334 * VNF simulation memory area.
336 uint64_t noisy_lkup_num_reads_writes;
339 * Receive Side Scaling (RSS) configuration.
341 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
344 * Port topology configuration
346 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
349 * Avoids to flush all the RX streams before starts forwarding.
351 uint8_t no_flush_rx = 0; /* flush by default */
354 * Flow API isolated mode.
356 uint8_t flow_isolate_all;
359 * Avoids to check link status when starting/stopping a port.
361 uint8_t no_link_check = 0; /* check by default */
364 * Don't automatically start all ports in interactive mode.
366 uint8_t no_device_start = 0;
369 * Enable link status change notification
371 uint8_t lsc_interrupt = 1; /* enabled by default */
374 * Enable device removal notification.
376 uint8_t rmv_interrupt = 1; /* enabled by default */
378 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
380 /* After attach, port setup is called on event or by iterator */
381 bool setup_on_probe_event = true;
383 /* Clear ptypes on port initialization. */
384 uint8_t clear_ptypes = true;
386 /* Hairpin ports configuration mode. */
387 uint16_t hairpin_mode;
389 /* Pretty printing of ethdev events */
390 static const char * const eth_event_desc[] = {
391 [RTE_ETH_EVENT_UNKNOWN] = "unknown",
392 [RTE_ETH_EVENT_INTR_LSC] = "link state change",
393 [RTE_ETH_EVENT_QUEUE_STATE] = "queue state",
394 [RTE_ETH_EVENT_INTR_RESET] = "reset",
395 [RTE_ETH_EVENT_VF_MBOX] = "VF mbox",
396 [RTE_ETH_EVENT_IPSEC] = "IPsec",
397 [RTE_ETH_EVENT_MACSEC] = "MACsec",
398 [RTE_ETH_EVENT_INTR_RMV] = "device removal",
399 [RTE_ETH_EVENT_NEW] = "device probed",
400 [RTE_ETH_EVENT_DESTROY] = "device released",
401 [RTE_ETH_EVENT_FLOW_AGED] = "flow aged",
402 [RTE_ETH_EVENT_MAX] = NULL,
406 * Display or mask ether events
407 * Default to all events except VF_MBOX
409 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
410 (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
411 (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
412 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
413 (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
414 (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
415 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV) |
416 (UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED);
418 * Decide if all memory are locked for performance.
423 * NIC bypass mode configuration options.
426 #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS
427 /* The NIC bypass watchdog timeout. */
428 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
432 #ifdef RTE_LIB_LATENCYSTATS
435 * Set when latency stats is enabled in the commandline
437 uint8_t latencystats_enabled;
440 * Lcore ID to serive latency statistics.
442 lcoreid_t latencystats_lcore_id = -1;
447 * Ethernet device configuration.
449 struct rte_eth_rxmode rx_mode = {
450 /* Default maximum frame length.
451 * Zero is converted to "RTE_ETHER_MTU + PMD Ethernet overhead"
457 struct rte_eth_txmode tx_mode = {
458 .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
461 struct rte_fdir_conf fdir_conf = {
462 .mode = RTE_FDIR_MODE_NONE,
463 .pballoc = RTE_FDIR_PBALLOC_64K,
464 .status = RTE_FDIR_REPORT_STATUS,
466 .vlan_tci_mask = 0xFFEF,
468 .src_ip = 0xFFFFFFFF,
469 .dst_ip = 0xFFFFFFFF,
472 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
473 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
475 .src_port_mask = 0xFFFF,
476 .dst_port_mask = 0xFFFF,
477 .mac_addr_byte_mask = 0xFF,
478 .tunnel_type_mask = 1,
479 .tunnel_id_mask = 0xFFFFFFFF,
484 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
487 * Display zero values by default for xstats
489 uint8_t xstats_hide_zero;
492 * Measure of CPU cycles disabled by default
494 uint8_t record_core_cycles;
497 * Display of RX and TX bursts disabled by default
499 uint8_t record_burst_stats;
501 unsigned int num_sockets = 0;
502 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
504 #ifdef RTE_LIB_BITRATESTATS
505 /* Bitrate statistics */
506 struct rte_stats_bitrates *bitrate_data;
507 lcoreid_t bitrate_lcore_id;
508 uint8_t bitrate_enabled;
511 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
512 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
515 * hexadecimal bitmask of RX mq mode can be enabled.
517 enum rte_eth_rx_mq_mode rx_mq_mode = ETH_MQ_RX_VMDQ_DCB_RSS;
520 * Used to set forced link speed
522 uint32_t eth_link_speed;
524 /* Forward function declarations */
525 static void setup_attached_port(portid_t pi);
526 static void check_all_ports_link_status(uint32_t port_mask);
527 static int eth_event_callback(portid_t port_id,
528 enum rte_eth_event_type type,
529 void *param, void *ret_param);
530 static void dev_event_callback(const char *device_name,
531 enum rte_dev_event_type type,
535 * Check if all the ports are started.
536 * If yes, return positive value. If not, return zero.
538 static int all_ports_started(void);
540 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
541 uint16_t gso_max_segment_size = RTE_ETHER_MAX_LEN - RTE_ETHER_CRC_LEN;
543 /* Holds the registered mbuf dynamic flags names. */
544 char dynf_names[64][RTE_MBUF_DYN_NAMESIZE];
547 * Helper function to check if socket is already discovered.
548 * If yes, return positive value. If not, return zero.
551 new_socket_id(unsigned int socket_id)
555 for (i = 0; i < num_sockets; i++) {
556 if (socket_ids[i] == socket_id)
563 * Setup default configuration.
566 set_default_fwd_lcores_config(void)
570 unsigned int sock_num;
573 for (i = 0; i < RTE_MAX_LCORE; i++) {
574 if (!rte_lcore_is_enabled(i))
576 sock_num = rte_lcore_to_socket_id(i);
577 if (new_socket_id(sock_num)) {
578 if (num_sockets >= RTE_MAX_NUMA_NODES) {
579 rte_exit(EXIT_FAILURE,
580 "Total sockets greater than %u\n",
583 socket_ids[num_sockets++] = sock_num;
585 if (i == rte_get_main_lcore())
587 fwd_lcores_cpuids[nb_lc++] = i;
589 nb_lcores = (lcoreid_t) nb_lc;
590 nb_cfg_lcores = nb_lcores;
595 set_def_peer_eth_addrs(void)
599 for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
600 peer_eth_addrs[i].addr_bytes[0] = RTE_ETHER_LOCAL_ADMIN_ADDR;
601 peer_eth_addrs[i].addr_bytes[5] = i;
606 set_default_fwd_ports_config(void)
611 RTE_ETH_FOREACH_DEV(pt_id) {
612 fwd_ports_ids[i++] = pt_id;
614 /* Update sockets info according to the attached device */
615 int socket_id = rte_eth_dev_socket_id(pt_id);
616 if (socket_id >= 0 && new_socket_id(socket_id)) {
617 if (num_sockets >= RTE_MAX_NUMA_NODES) {
618 rte_exit(EXIT_FAILURE,
619 "Total sockets greater than %u\n",
622 socket_ids[num_sockets++] = socket_id;
626 nb_cfg_ports = nb_ports;
627 nb_fwd_ports = nb_ports;
631 set_def_fwd_config(void)
633 set_default_fwd_lcores_config();
634 set_def_peer_eth_addrs();
635 set_default_fwd_ports_config();
638 #ifndef RTE_EXEC_ENV_WINDOWS
639 /* extremely pessimistic estimation of memory required to create a mempool */
641 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
643 unsigned int n_pages, mbuf_per_pg, leftover;
644 uint64_t total_mem, mbuf_mem, obj_sz;
646 /* there is no good way to predict how much space the mempool will
647 * occupy because it will allocate chunks on the fly, and some of those
648 * will come from default DPDK memory while some will come from our
649 * external memory, so just assume 128MB will be enough for everyone.
651 uint64_t hdr_mem = 128 << 20;
653 /* account for possible non-contiguousness */
654 obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL);
656 TESTPMD_LOG(ERR, "Object size is bigger than page size\n");
660 mbuf_per_pg = pgsz / obj_sz;
661 leftover = (nb_mbufs % mbuf_per_pg) > 0;
662 n_pages = (nb_mbufs / mbuf_per_pg) + leftover;
664 mbuf_mem = n_pages * pgsz;
666 total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz);
668 if (total_mem > SIZE_MAX) {
669 TESTPMD_LOG(ERR, "Memory size too big\n");
672 *out = (size_t)total_mem;
678 pagesz_flags(uint64_t page_sz)
680 /* as per mmap() manpage, all page sizes are log2 of page size
681 * shifted by MAP_HUGE_SHIFT
683 int log2 = rte_log2_u64(page_sz);
685 return (log2 << HUGE_SHIFT);
689 alloc_mem(size_t memsz, size_t pgsz, bool huge)
694 /* allocate anonymous hugepages */
695 flags = MAP_ANONYMOUS | MAP_PRIVATE;
697 flags |= HUGE_FLAG | pagesz_flags(pgsz);
699 addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0);
700 if (addr == MAP_FAILED)
706 struct extmem_param {
710 rte_iova_t *iova_table;
711 unsigned int iova_table_len;
715 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param,
718 uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */
719 RTE_PGSIZE_16M, RTE_PGSIZE_16G}; /* POWER */
720 unsigned int cur_page, n_pages, pgsz_idx;
721 size_t mem_sz, cur_pgsz;
722 rte_iova_t *iovas = NULL;
726 for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) {
727 /* skip anything that is too big */
728 if (pgsizes[pgsz_idx] > SIZE_MAX)
731 cur_pgsz = pgsizes[pgsz_idx];
733 /* if we were told not to allocate hugepages, override */
735 cur_pgsz = sysconf(_SC_PAGESIZE);
737 ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz);
739 TESTPMD_LOG(ERR, "Cannot calculate memory size\n");
743 /* allocate our memory */
744 addr = alloc_mem(mem_sz, cur_pgsz, huge);
746 /* if we couldn't allocate memory with a specified page size,
747 * that doesn't mean we can't do it with other page sizes, so
753 /* store IOVA addresses for every page in this memory area */
754 n_pages = mem_sz / cur_pgsz;
756 iovas = malloc(sizeof(*iovas) * n_pages);
759 TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n");
762 /* lock memory if it's not huge pages */
766 /* populate IOVA addresses */
767 for (cur_page = 0; cur_page < n_pages; cur_page++) {
772 offset = cur_pgsz * cur_page;
773 cur = RTE_PTR_ADD(addr, offset);
775 /* touch the page before getting its IOVA */
776 *(volatile char *)cur = 0;
778 iova = rte_mem_virt2iova(cur);
780 iovas[cur_page] = iova;
785 /* if we couldn't allocate anything */
791 param->pgsz = cur_pgsz;
792 param->iova_table = iovas;
793 param->iova_table_len = n_pages;
800 munmap(addr, mem_sz);
806 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge)
808 struct extmem_param param;
811 memset(¶m, 0, sizeof(param));
813 /* check if our heap exists */
814 socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
816 /* create our heap */
817 ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME);
819 TESTPMD_LOG(ERR, "Cannot create heap\n");
824 ret = create_extmem(nb_mbufs, mbuf_sz, ¶m, huge);
826 TESTPMD_LOG(ERR, "Cannot create memory area\n");
830 /* we now have a valid memory area, so add it to heap */
831 ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME,
832 param.addr, param.len, param.iova_table,
833 param.iova_table_len, param.pgsz);
835 /* when using VFIO, memory is automatically mapped for DMA by EAL */
837 /* not needed any more */
838 free(param.iova_table);
841 TESTPMD_LOG(ERR, "Cannot add memory to heap\n");
842 munmap(param.addr, param.len);
848 TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n",
854 dma_unmap_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused,
855 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused)
860 RTE_ETH_FOREACH_DEV(pid) {
861 struct rte_eth_dev_info dev_info;
863 ret = eth_dev_info_get_print_err(pid, &dev_info);
866 "unable to get device info for port %d on addr 0x%p,"
867 "mempool unmapping will not be performed\n",
872 ret = rte_dev_dma_unmap(dev_info.device, memhdr->addr, 0, memhdr->len);
875 "unable to DMA unmap addr 0x%p "
877 memhdr->addr, dev_info.device->name);
880 ret = rte_extmem_unregister(memhdr->addr, memhdr->len);
883 "unable to un-register addr 0x%p\n", memhdr->addr);
888 dma_map_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused,
889 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused)
892 size_t page_size = sysconf(_SC_PAGESIZE);
895 ret = rte_extmem_register(memhdr->addr, memhdr->len, NULL, 0,
899 "unable to register addr 0x%p\n", memhdr->addr);
902 RTE_ETH_FOREACH_DEV(pid) {
903 struct rte_eth_dev_info dev_info;
905 ret = eth_dev_info_get_print_err(pid, &dev_info);
908 "unable to get device info for port %d on addr 0x%p,"
909 "mempool mapping will not be performed\n",
913 ret = rte_dev_dma_map(dev_info.device, memhdr->addr, 0, memhdr->len);
916 "unable to DMA map addr 0x%p "
918 memhdr->addr, dev_info.device->name);
925 setup_extbuf(uint32_t nb_mbufs, uint16_t mbuf_sz, unsigned int socket_id,
926 char *pool_name, struct rte_pktmbuf_extmem **ext_mem)
928 struct rte_pktmbuf_extmem *xmem;
929 unsigned int ext_num, zone_num, elt_num;
932 elt_size = RTE_ALIGN_CEIL(mbuf_sz, RTE_CACHE_LINE_SIZE);
933 elt_num = EXTBUF_ZONE_SIZE / elt_size;
934 zone_num = (nb_mbufs + elt_num - 1) / elt_num;
936 xmem = malloc(sizeof(struct rte_pktmbuf_extmem) * zone_num);
938 TESTPMD_LOG(ERR, "Cannot allocate memory for "
939 "external buffer descriptors\n");
943 for (ext_num = 0; ext_num < zone_num; ext_num++) {
944 struct rte_pktmbuf_extmem *xseg = xmem + ext_num;
945 const struct rte_memzone *mz;
946 char mz_name[RTE_MEMZONE_NAMESIZE];
949 ret = snprintf(mz_name, sizeof(mz_name),
950 RTE_MEMPOOL_MZ_FORMAT "_xb_%u", pool_name, ext_num);
951 if (ret < 0 || ret >= (int)sizeof(mz_name)) {
952 errno = ENAMETOOLONG;
956 mz = rte_memzone_reserve_aligned(mz_name, EXTBUF_ZONE_SIZE,
958 RTE_MEMZONE_IOVA_CONTIG |
960 RTE_MEMZONE_SIZE_HINT_ONLY,
964 * The caller exits on external buffer creation
965 * error, so there is no need to free memzones.
971 xseg->buf_ptr = mz->addr;
972 xseg->buf_iova = mz->iova;
973 xseg->buf_len = EXTBUF_ZONE_SIZE;
974 xseg->elt_size = elt_size;
976 if (ext_num == 0 && xmem != NULL) {
985 * Configuration initialisation done once at init time.
987 static struct rte_mempool *
988 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
989 unsigned int socket_id, uint16_t size_idx)
991 char pool_name[RTE_MEMPOOL_NAMESIZE];
992 struct rte_mempool *rte_mp = NULL;
993 #ifndef RTE_EXEC_ENV_WINDOWS
996 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
998 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name), size_idx);
1001 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
1002 pool_name, nb_mbuf, mbuf_seg_size, socket_id);
1004 switch (mp_alloc_type) {
1005 case MP_ALLOC_NATIVE:
1007 /* wrapper to rte_mempool_create() */
1008 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
1009 rte_mbuf_best_mempool_ops());
1010 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
1011 mb_mempool_cache, 0, mbuf_seg_size, socket_id);
1014 #ifndef RTE_EXEC_ENV_WINDOWS
1017 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
1018 mb_size, (unsigned int) mb_mempool_cache,
1019 sizeof(struct rte_pktmbuf_pool_private),
1020 socket_id, mempool_flags);
1024 if (rte_mempool_populate_anon(rte_mp) == 0) {
1025 rte_mempool_free(rte_mp);
1029 rte_pktmbuf_pool_init(rte_mp, NULL);
1030 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
1031 rte_mempool_mem_iter(rte_mp, dma_map_cb, NULL);
1035 case MP_ALLOC_XMEM_HUGE:
1038 bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE;
1040 if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0)
1041 rte_exit(EXIT_FAILURE, "Could not create external memory\n");
1044 rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
1045 if (heap_socket < 0)
1046 rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n");
1048 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
1049 rte_mbuf_best_mempool_ops());
1050 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
1051 mb_mempool_cache, 0, mbuf_seg_size,
1058 struct rte_pktmbuf_extmem *ext_mem;
1059 unsigned int ext_num;
1061 ext_num = setup_extbuf(nb_mbuf, mbuf_seg_size,
1062 socket_id, pool_name, &ext_mem);
1064 rte_exit(EXIT_FAILURE,
1065 "Can't create pinned data buffers\n");
1067 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
1068 rte_mbuf_best_mempool_ops());
1069 rte_mp = rte_pktmbuf_pool_create_extbuf
1070 (pool_name, nb_mbuf, mb_mempool_cache,
1071 0, mbuf_seg_size, socket_id,
1078 rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
1082 #ifndef RTE_EXEC_ENV_WINDOWS
1085 if (rte_mp == NULL) {
1086 rte_exit(EXIT_FAILURE,
1087 "Creation of mbuf pool for socket %u failed: %s\n",
1088 socket_id, rte_strerror(rte_errno));
1089 } else if (verbose_level > 0) {
1090 rte_mempool_dump(stdout, rte_mp);
1096 * Check given socket id is valid or not with NUMA mode,
1097 * if valid, return 0, else return -1
1100 check_socket_id(const unsigned int socket_id)
1102 static int warning_once = 0;
1104 if (new_socket_id(socket_id)) {
1105 if (!warning_once && numa_support)
1107 "Warning: NUMA should be configured manually by using --port-numa-config and --ring-numa-config parameters along with --numa.\n");
1115 * Get the allowed maximum number of RX queues.
1116 * *pid return the port id which has minimal value of
1117 * max_rx_queues in all ports.
1120 get_allowed_max_nb_rxq(portid_t *pid)
1122 queueid_t allowed_max_rxq = RTE_MAX_QUEUES_PER_PORT;
1123 bool max_rxq_valid = false;
1125 struct rte_eth_dev_info dev_info;
1127 RTE_ETH_FOREACH_DEV(pi) {
1128 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1131 max_rxq_valid = true;
1132 if (dev_info.max_rx_queues < allowed_max_rxq) {
1133 allowed_max_rxq = dev_info.max_rx_queues;
1137 return max_rxq_valid ? allowed_max_rxq : 0;
1141 * Check input rxq is valid or not.
1142 * If input rxq is not greater than any of maximum number
1143 * of RX queues of all ports, it is valid.
1144 * if valid, return 0, else return -1
1147 check_nb_rxq(queueid_t rxq)
1149 queueid_t allowed_max_rxq;
1152 allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
1153 if (rxq > allowed_max_rxq) {
1155 "Fail: input rxq (%u) can't be greater than max_rx_queues (%u) of port %u\n",
1156 rxq, allowed_max_rxq, pid);
1163 * Get the allowed maximum number of TX queues.
1164 * *pid return the port id which has minimal value of
1165 * max_tx_queues in all ports.
1168 get_allowed_max_nb_txq(portid_t *pid)
1170 queueid_t allowed_max_txq = RTE_MAX_QUEUES_PER_PORT;
1171 bool max_txq_valid = false;
1173 struct rte_eth_dev_info dev_info;
1175 RTE_ETH_FOREACH_DEV(pi) {
1176 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1179 max_txq_valid = true;
1180 if (dev_info.max_tx_queues < allowed_max_txq) {
1181 allowed_max_txq = dev_info.max_tx_queues;
1185 return max_txq_valid ? allowed_max_txq : 0;
1189 * Check input txq is valid or not.
1190 * If input txq is not greater than any of maximum number
1191 * of TX queues of all ports, it is valid.
1192 * if valid, return 0, else return -1
1195 check_nb_txq(queueid_t txq)
1197 queueid_t allowed_max_txq;
1200 allowed_max_txq = get_allowed_max_nb_txq(&pid);
1201 if (txq > allowed_max_txq) {
1203 "Fail: input txq (%u) can't be greater than max_tx_queues (%u) of port %u\n",
1204 txq, allowed_max_txq, pid);
1211 * Get the allowed maximum number of RXDs of every rx queue.
1212 * *pid return the port id which has minimal value of
1213 * max_rxd in all queues of all ports.
1216 get_allowed_max_nb_rxd(portid_t *pid)
1218 uint16_t allowed_max_rxd = UINT16_MAX;
1220 struct rte_eth_dev_info dev_info;
1222 RTE_ETH_FOREACH_DEV(pi) {
1223 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1226 if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) {
1227 allowed_max_rxd = dev_info.rx_desc_lim.nb_max;
1231 return allowed_max_rxd;
1235 * Get the allowed minimal number of RXDs of every rx queue.
1236 * *pid return the port id which has minimal value of
1237 * min_rxd in all queues of all ports.
1240 get_allowed_min_nb_rxd(portid_t *pid)
1242 uint16_t allowed_min_rxd = 0;
1244 struct rte_eth_dev_info dev_info;
1246 RTE_ETH_FOREACH_DEV(pi) {
1247 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1250 if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) {
1251 allowed_min_rxd = dev_info.rx_desc_lim.nb_min;
1256 return allowed_min_rxd;
1260 * Check input rxd is valid or not.
1261 * If input rxd is not greater than any of maximum number
1262 * of RXDs of every Rx queues and is not less than any of
1263 * minimal number of RXDs of every Rx queues, it is valid.
1264 * if valid, return 0, else return -1
1267 check_nb_rxd(queueid_t rxd)
1269 uint16_t allowed_max_rxd;
1270 uint16_t allowed_min_rxd;
1273 allowed_max_rxd = get_allowed_max_nb_rxd(&pid);
1274 if (rxd > allowed_max_rxd) {
1276 "Fail: input rxd (%u) can't be greater than max_rxds (%u) of port %u\n",
1277 rxd, allowed_max_rxd, pid);
1281 allowed_min_rxd = get_allowed_min_nb_rxd(&pid);
1282 if (rxd < allowed_min_rxd) {
1284 "Fail: input rxd (%u) can't be less than min_rxds (%u) of port %u\n",
1285 rxd, allowed_min_rxd, pid);
1293 * Get the allowed maximum number of TXDs of every rx queues.
1294 * *pid return the port id which has minimal value of
1295 * max_txd in every tx queue.
1298 get_allowed_max_nb_txd(portid_t *pid)
1300 uint16_t allowed_max_txd = UINT16_MAX;
1302 struct rte_eth_dev_info dev_info;
1304 RTE_ETH_FOREACH_DEV(pi) {
1305 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1308 if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) {
1309 allowed_max_txd = dev_info.tx_desc_lim.nb_max;
1313 return allowed_max_txd;
1317 * Get the allowed maximum number of TXDs of every tx queues.
1318 * *pid return the port id which has minimal value of
1319 * min_txd in every tx queue.
1322 get_allowed_min_nb_txd(portid_t *pid)
1324 uint16_t allowed_min_txd = 0;
1326 struct rte_eth_dev_info dev_info;
1328 RTE_ETH_FOREACH_DEV(pi) {
1329 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1332 if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) {
1333 allowed_min_txd = dev_info.tx_desc_lim.nb_min;
1338 return allowed_min_txd;
1342 * Check input txd is valid or not.
1343 * If input txd is not greater than any of maximum number
1344 * of TXDs of every Rx queues, it is valid.
1345 * if valid, return 0, else return -1
1348 check_nb_txd(queueid_t txd)
1350 uint16_t allowed_max_txd;
1351 uint16_t allowed_min_txd;
1354 allowed_max_txd = get_allowed_max_nb_txd(&pid);
1355 if (txd > allowed_max_txd) {
1357 "Fail: input txd (%u) can't be greater than max_txds (%u) of port %u\n",
1358 txd, allowed_max_txd, pid);
1362 allowed_min_txd = get_allowed_min_nb_txd(&pid);
1363 if (txd < allowed_min_txd) {
1365 "Fail: input txd (%u) can't be less than min_txds (%u) of port %u\n",
1366 txd, allowed_min_txd, pid);
1374 * Get the allowed maximum number of hairpin queues.
1375 * *pid return the port id which has minimal value of
1376 * max_hairpin_queues in all ports.
1379 get_allowed_max_nb_hairpinq(portid_t *pid)
1381 queueid_t allowed_max_hairpinq = RTE_MAX_QUEUES_PER_PORT;
1383 struct rte_eth_hairpin_cap cap;
1385 RTE_ETH_FOREACH_DEV(pi) {
1386 if (rte_eth_dev_hairpin_capability_get(pi, &cap) != 0) {
1390 if (cap.max_nb_queues < allowed_max_hairpinq) {
1391 allowed_max_hairpinq = cap.max_nb_queues;
1395 return allowed_max_hairpinq;
1399 * Check input hairpin is valid or not.
1400 * If input hairpin is not greater than any of maximum number
1401 * of hairpin queues of all ports, it is valid.
1402 * if valid, return 0, else return -1
1405 check_nb_hairpinq(queueid_t hairpinq)
1407 queueid_t allowed_max_hairpinq;
1410 allowed_max_hairpinq = get_allowed_max_nb_hairpinq(&pid);
1411 if (hairpinq > allowed_max_hairpinq) {
1413 "Fail: input hairpin (%u) can't be greater than max_hairpin_queues (%u) of port %u\n",
1414 hairpinq, allowed_max_hairpinq, pid);
1421 init_config_port_offloads(portid_t pid, uint32_t socket_id)
1423 struct rte_port *port = &ports[pid];
1428 port->dev_conf.txmode = tx_mode;
1429 port->dev_conf.rxmode = rx_mode;
1431 ret = eth_dev_info_get_print_err(pid, &port->dev_info);
1433 rte_exit(EXIT_FAILURE, "rte_eth_dev_info_get() failed\n");
1435 ret = update_jumbo_frame_offload(pid);
1438 "Updating jumbo frame offload failed for port %u\n",
1441 if (!(port->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE))
1442 port->dev_conf.txmode.offloads &=
1443 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
1445 /* Apply Rx offloads configuration */
1446 for (i = 0; i < port->dev_info.max_rx_queues; i++)
1447 port->rx_conf[i].offloads = port->dev_conf.rxmode.offloads;
1448 /* Apply Tx offloads configuration */
1449 for (i = 0; i < port->dev_info.max_tx_queues; i++)
1450 port->tx_conf[i].offloads = port->dev_conf.txmode.offloads;
1453 port->dev_conf.link_speeds = eth_link_speed;
1455 /* set flag to initialize port/queue */
1456 port->need_reconfig = 1;
1457 port->need_reconfig_queues = 1;
1458 port->socket_id = socket_id;
1459 port->tx_metadata = 0;
1462 * Check for maximum number of segments per MTU.
1463 * Accordingly update the mbuf data size.
1465 if (port->dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX &&
1466 port->dev_info.rx_desc_lim.nb_mtu_seg_max != 0) {
1467 data_size = rx_mode.max_rx_pkt_len /
1468 port->dev_info.rx_desc_lim.nb_mtu_seg_max;
1470 if ((data_size + RTE_PKTMBUF_HEADROOM) > mbuf_data_size[0]) {
1471 mbuf_data_size[0] = data_size + RTE_PKTMBUF_HEADROOM;
1472 TESTPMD_LOG(WARNING,
1473 "Configured mbuf size of the first segment %hu\n",
1483 struct rte_mempool *mbp;
1484 unsigned int nb_mbuf_per_pool;
1486 struct rte_gro_param gro_param;
1489 /* Configuration of logical cores. */
1490 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
1491 sizeof(struct fwd_lcore *) * nb_lcores,
1492 RTE_CACHE_LINE_SIZE);
1493 if (fwd_lcores == NULL) {
1494 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
1495 "failed\n", nb_lcores);
1497 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1498 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
1499 sizeof(struct fwd_lcore),
1500 RTE_CACHE_LINE_SIZE);
1501 if (fwd_lcores[lc_id] == NULL) {
1502 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
1505 fwd_lcores[lc_id]->cpuid_idx = lc_id;
1508 RTE_ETH_FOREACH_DEV(pid) {
1512 socket_id = port_numa[pid];
1513 if (port_numa[pid] == NUMA_NO_CONFIG) {
1514 socket_id = rte_eth_dev_socket_id(pid);
1517 * if socket_id is invalid,
1518 * set to the first available socket.
1520 if (check_socket_id(socket_id) < 0)
1521 socket_id = socket_ids[0];
1524 socket_id = (socket_num == UMA_NO_CONFIG) ?
1527 /* Apply default TxRx configuration for all ports */
1528 init_config_port_offloads(pid, socket_id);
1531 * Create pools of mbuf.
1532 * If NUMA support is disabled, create a single pool of mbuf in
1533 * socket 0 memory by default.
1534 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
1536 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
1537 * nb_txd can be configured at run time.
1539 if (param_total_num_mbufs)
1540 nb_mbuf_per_pool = param_total_num_mbufs;
1542 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
1543 (nb_lcores * mb_mempool_cache) +
1544 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
1545 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
1551 for (i = 0; i < num_sockets; i++)
1552 for (j = 0; j < mbuf_data_size_n; j++)
1553 mempools[i * MAX_SEGS_BUFFER_SPLIT + j] =
1554 mbuf_pool_create(mbuf_data_size[j],
1560 for (i = 0; i < mbuf_data_size_n; i++)
1561 mempools[i] = mbuf_pool_create
1564 socket_num == UMA_NO_CONFIG ?
1570 gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
1571 DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
1573 * Records which Mbuf pool to use by each logical core, if needed.
1575 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1576 mbp = mbuf_pool_find(
1577 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]), 0);
1580 mbp = mbuf_pool_find(0, 0);
1581 fwd_lcores[lc_id]->mbp = mbp;
1582 /* initialize GSO context */
1583 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
1584 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
1585 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
1586 fwd_lcores[lc_id]->gso_ctx.gso_size = RTE_ETHER_MAX_LEN -
1588 fwd_lcores[lc_id]->gso_ctx.flag = 0;
1593 /* create a gro context for each lcore */
1594 gro_param.gro_types = RTE_GRO_TCP_IPV4;
1595 gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
1596 gro_param.max_item_per_flow = MAX_PKT_BURST;
1597 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1598 gro_param.socket_id = rte_lcore_to_socket_id(
1599 fwd_lcores_cpuids[lc_id]);
1600 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
1601 if (fwd_lcores[lc_id]->gro_ctx == NULL) {
1602 rte_exit(EXIT_FAILURE,
1603 "rte_gro_ctx_create() failed\n");
1610 reconfig(portid_t new_port_id, unsigned socket_id)
1612 /* Reconfiguration of Ethernet ports. */
1613 init_config_port_offloads(new_port_id, socket_id);
1619 init_fwd_streams(void)
1622 struct rte_port *port;
1623 streamid_t sm_id, nb_fwd_streams_new;
1626 /* set socket id according to numa or not */
1627 RTE_ETH_FOREACH_DEV(pid) {
1629 if (nb_rxq > port->dev_info.max_rx_queues) {
1631 "Fail: nb_rxq(%d) is greater than max_rx_queues(%d)\n",
1632 nb_rxq, port->dev_info.max_rx_queues);
1635 if (nb_txq > port->dev_info.max_tx_queues) {
1637 "Fail: nb_txq(%d) is greater than max_tx_queues(%d)\n",
1638 nb_txq, port->dev_info.max_tx_queues);
1642 if (port_numa[pid] != NUMA_NO_CONFIG)
1643 port->socket_id = port_numa[pid];
1645 port->socket_id = rte_eth_dev_socket_id(pid);
1648 * if socket_id is invalid,
1649 * set to the first available socket.
1651 if (check_socket_id(port->socket_id) < 0)
1652 port->socket_id = socket_ids[0];
1656 if (socket_num == UMA_NO_CONFIG)
1657 port->socket_id = 0;
1659 port->socket_id = socket_num;
1663 q = RTE_MAX(nb_rxq, nb_txq);
1666 "Fail: Cannot allocate fwd streams as number of queues is 0\n");
1669 nb_fwd_streams_new = (streamid_t)(nb_ports * q);
1670 if (nb_fwd_streams_new == nb_fwd_streams)
1673 if (fwd_streams != NULL) {
1674 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1675 if (fwd_streams[sm_id] == NULL)
1677 rte_free(fwd_streams[sm_id]);
1678 fwd_streams[sm_id] = NULL;
1680 rte_free(fwd_streams);
1685 nb_fwd_streams = nb_fwd_streams_new;
1686 if (nb_fwd_streams) {
1687 fwd_streams = rte_zmalloc("testpmd: fwd_streams",
1688 sizeof(struct fwd_stream *) * nb_fwd_streams,
1689 RTE_CACHE_LINE_SIZE);
1690 if (fwd_streams == NULL)
1691 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
1692 " (struct fwd_stream *)) failed\n",
1695 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1696 fwd_streams[sm_id] = rte_zmalloc("testpmd:"
1697 " struct fwd_stream", sizeof(struct fwd_stream),
1698 RTE_CACHE_LINE_SIZE);
1699 if (fwd_streams[sm_id] == NULL)
1700 rte_exit(EXIT_FAILURE, "rte_zmalloc"
1701 "(struct fwd_stream) failed\n");
1709 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
1711 uint64_t total_burst, sburst;
1713 uint64_t burst_stats[4];
1714 uint16_t pktnb_stats[4];
1716 int burst_percent[4], sburstp;
1720 * First compute the total number of packet bursts and the
1721 * two highest numbers of bursts of the same number of packets.
1723 memset(&burst_stats, 0x0, sizeof(burst_stats));
1724 memset(&pktnb_stats, 0x0, sizeof(pktnb_stats));
1726 /* Show stats for 0 burst size always */
1727 total_burst = pbs->pkt_burst_spread[0];
1728 burst_stats[0] = pbs->pkt_burst_spread[0];
1731 /* Find the next 2 burst sizes with highest occurrences. */
1732 for (nb_pkt = 1; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
1733 nb_burst = pbs->pkt_burst_spread[nb_pkt];
1738 total_burst += nb_burst;
1740 if (nb_burst > burst_stats[1]) {
1741 burst_stats[2] = burst_stats[1];
1742 pktnb_stats[2] = pktnb_stats[1];
1743 burst_stats[1] = nb_burst;
1744 pktnb_stats[1] = nb_pkt;
1745 } else if (nb_burst > burst_stats[2]) {
1746 burst_stats[2] = nb_burst;
1747 pktnb_stats[2] = nb_pkt;
1750 if (total_burst == 0)
1753 printf(" %s-bursts : %"PRIu64" [", rx_tx, total_burst);
1754 for (i = 0, sburst = 0, sburstp = 0; i < 4; i++) {
1756 printf("%d%% of other]\n", 100 - sburstp);
1760 sburst += burst_stats[i];
1761 if (sburst == total_burst) {
1762 printf("%d%% of %d pkts]\n",
1763 100 - sburstp, (int) pktnb_stats[i]);
1768 (double)burst_stats[i] / total_burst * 100;
1769 printf("%d%% of %d pkts + ",
1770 burst_percent[i], (int) pktnb_stats[i]);
1771 sburstp += burst_percent[i];
1776 fwd_stream_stats_display(streamid_t stream_id)
1778 struct fwd_stream *fs;
1779 static const char *fwd_top_stats_border = "-------";
1781 fs = fwd_streams[stream_id];
1782 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1783 (fs->fwd_dropped == 0))
1785 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1786 "TX Port=%2d/Queue=%2d %s\n",
1787 fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1788 fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1789 printf(" RX-packets: %-14"PRIu64" TX-packets: %-14"PRIu64
1790 " TX-dropped: %-14"PRIu64,
1791 fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1793 /* if checksum mode */
1794 if (cur_fwd_eng == &csum_fwd_engine) {
1795 printf(" RX- bad IP checksum: %-14"PRIu64
1796 " Rx- bad L4 checksum: %-14"PRIu64
1797 " Rx- bad outer L4 checksum: %-14"PRIu64"\n",
1798 fs->rx_bad_ip_csum, fs->rx_bad_l4_csum,
1799 fs->rx_bad_outer_l4_csum);
1800 printf(" RX- bad outer IP checksum: %-14"PRIu64"\n",
1801 fs->rx_bad_outer_ip_csum);
1806 if (record_burst_stats) {
1807 pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1808 pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1813 fwd_stats_display(void)
1815 static const char *fwd_stats_border = "----------------------";
1816 static const char *acc_stats_border = "+++++++++++++++";
1818 struct fwd_stream *rx_stream;
1819 struct fwd_stream *tx_stream;
1820 uint64_t tx_dropped;
1821 uint64_t rx_bad_ip_csum;
1822 uint64_t rx_bad_l4_csum;
1823 uint64_t rx_bad_outer_l4_csum;
1824 uint64_t rx_bad_outer_ip_csum;
1825 } ports_stats[RTE_MAX_ETHPORTS];
1826 uint64_t total_rx_dropped = 0;
1827 uint64_t total_tx_dropped = 0;
1828 uint64_t total_rx_nombuf = 0;
1829 struct rte_eth_stats stats;
1830 uint64_t fwd_cycles = 0;
1831 uint64_t total_recv = 0;
1832 uint64_t total_xmit = 0;
1833 struct rte_port *port;
1838 memset(ports_stats, 0, sizeof(ports_stats));
1840 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1841 struct fwd_stream *fs = fwd_streams[sm_id];
1843 if (cur_fwd_config.nb_fwd_streams >
1844 cur_fwd_config.nb_fwd_ports) {
1845 fwd_stream_stats_display(sm_id);
1847 ports_stats[fs->tx_port].tx_stream = fs;
1848 ports_stats[fs->rx_port].rx_stream = fs;
1851 ports_stats[fs->tx_port].tx_dropped += fs->fwd_dropped;
1853 ports_stats[fs->rx_port].rx_bad_ip_csum += fs->rx_bad_ip_csum;
1854 ports_stats[fs->rx_port].rx_bad_l4_csum += fs->rx_bad_l4_csum;
1855 ports_stats[fs->rx_port].rx_bad_outer_l4_csum +=
1856 fs->rx_bad_outer_l4_csum;
1857 ports_stats[fs->rx_port].rx_bad_outer_ip_csum +=
1858 fs->rx_bad_outer_ip_csum;
1860 if (record_core_cycles)
1861 fwd_cycles += fs->core_cycles;
1863 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1864 pt_id = fwd_ports_ids[i];
1865 port = &ports[pt_id];
1867 rte_eth_stats_get(pt_id, &stats);
1868 stats.ipackets -= port->stats.ipackets;
1869 stats.opackets -= port->stats.opackets;
1870 stats.ibytes -= port->stats.ibytes;
1871 stats.obytes -= port->stats.obytes;
1872 stats.imissed -= port->stats.imissed;
1873 stats.oerrors -= port->stats.oerrors;
1874 stats.rx_nombuf -= port->stats.rx_nombuf;
1876 total_recv += stats.ipackets;
1877 total_xmit += stats.opackets;
1878 total_rx_dropped += stats.imissed;
1879 total_tx_dropped += ports_stats[pt_id].tx_dropped;
1880 total_tx_dropped += stats.oerrors;
1881 total_rx_nombuf += stats.rx_nombuf;
1883 printf("\n %s Forward statistics for port %-2d %s\n",
1884 fwd_stats_border, pt_id, fwd_stats_border);
1886 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64
1887 "RX-total: %-"PRIu64"\n", stats.ipackets, stats.imissed,
1888 stats.ipackets + stats.imissed);
1890 if (cur_fwd_eng == &csum_fwd_engine) {
1891 printf(" Bad-ipcsum: %-14"PRIu64
1892 " Bad-l4csum: %-14"PRIu64
1893 "Bad-outer-l4csum: %-14"PRIu64"\n",
1894 ports_stats[pt_id].rx_bad_ip_csum,
1895 ports_stats[pt_id].rx_bad_l4_csum,
1896 ports_stats[pt_id].rx_bad_outer_l4_csum);
1897 printf(" Bad-outer-ipcsum: %-14"PRIu64"\n",
1898 ports_stats[pt_id].rx_bad_outer_ip_csum);
1900 if (stats.ierrors + stats.rx_nombuf > 0) {
1901 printf(" RX-error: %-"PRIu64"\n", stats.ierrors);
1902 printf(" RX-nombufs: %-14"PRIu64"\n", stats.rx_nombuf);
1905 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64
1906 "TX-total: %-"PRIu64"\n",
1907 stats.opackets, ports_stats[pt_id].tx_dropped,
1908 stats.opackets + ports_stats[pt_id].tx_dropped);
1910 if (record_burst_stats) {
1911 if (ports_stats[pt_id].rx_stream)
1912 pkt_burst_stats_display("RX",
1913 &ports_stats[pt_id].rx_stream->rx_burst_stats);
1914 if (ports_stats[pt_id].tx_stream)
1915 pkt_burst_stats_display("TX",
1916 &ports_stats[pt_id].tx_stream->tx_burst_stats);
1919 printf(" %s--------------------------------%s\n",
1920 fwd_stats_border, fwd_stats_border);
1923 printf("\n %s Accumulated forward statistics for all ports"
1925 acc_stats_border, acc_stats_border);
1926 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1928 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1930 total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1931 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1932 if (total_rx_nombuf > 0)
1933 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1934 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++"
1936 acc_stats_border, acc_stats_border);
1937 if (record_core_cycles) {
1938 #define CYC_PER_MHZ 1E6
1939 if (total_recv > 0 || total_xmit > 0) {
1940 uint64_t total_pkts = 0;
1941 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 ||
1942 strcmp(cur_fwd_eng->fwd_mode_name, "flowgen") == 0)
1943 total_pkts = total_xmit;
1945 total_pkts = total_recv;
1947 printf("\n CPU cycles/packet=%.2F (total cycles="
1948 "%"PRIu64" / total %s packets=%"PRIu64") at %"PRIu64
1950 (double) fwd_cycles / total_pkts,
1951 fwd_cycles, cur_fwd_eng->fwd_mode_name, total_pkts,
1952 (uint64_t)(rte_get_tsc_hz() / CYC_PER_MHZ));
1958 fwd_stats_reset(void)
1964 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1965 pt_id = fwd_ports_ids[i];
1966 rte_eth_stats_get(pt_id, &ports[pt_id].stats);
1968 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1969 struct fwd_stream *fs = fwd_streams[sm_id];
1973 fs->fwd_dropped = 0;
1974 fs->rx_bad_ip_csum = 0;
1975 fs->rx_bad_l4_csum = 0;
1976 fs->rx_bad_outer_l4_csum = 0;
1977 fs->rx_bad_outer_ip_csum = 0;
1979 memset(&fs->rx_burst_stats, 0, sizeof(fs->rx_burst_stats));
1980 memset(&fs->tx_burst_stats, 0, sizeof(fs->tx_burst_stats));
1981 fs->core_cycles = 0;
1986 flush_fwd_rx_queues(void)
1988 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1995 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1996 uint64_t timer_period;
1998 /* convert to number of cycles */
1999 timer_period = rte_get_timer_hz(); /* 1 second timeout */
2001 for (j = 0; j < 2; j++) {
2002 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
2003 for (rxq = 0; rxq < nb_rxq; rxq++) {
2004 port_id = fwd_ports_ids[rxp];
2006 * testpmd can stuck in the below do while loop
2007 * if rte_eth_rx_burst() always returns nonzero
2008 * packets. So timer is added to exit this loop
2009 * after 1sec timer expiry.
2011 prev_tsc = rte_rdtsc();
2013 nb_rx = rte_eth_rx_burst(port_id, rxq,
2014 pkts_burst, MAX_PKT_BURST);
2015 for (i = 0; i < nb_rx; i++)
2016 rte_pktmbuf_free(pkts_burst[i]);
2018 cur_tsc = rte_rdtsc();
2019 diff_tsc = cur_tsc - prev_tsc;
2020 timer_tsc += diff_tsc;
2021 } while ((nb_rx > 0) &&
2022 (timer_tsc < timer_period));
2026 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
2031 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
2033 struct fwd_stream **fsm;
2036 #ifdef RTE_LIB_BITRATESTATS
2037 uint64_t tics_per_1sec;
2038 uint64_t tics_datum;
2039 uint64_t tics_current;
2040 uint16_t i, cnt_ports;
2042 cnt_ports = nb_ports;
2043 tics_datum = rte_rdtsc();
2044 tics_per_1sec = rte_get_timer_hz();
2046 fsm = &fwd_streams[fc->stream_idx];
2047 nb_fs = fc->stream_nb;
2049 for (sm_id = 0; sm_id < nb_fs; sm_id++)
2050 (*pkt_fwd)(fsm[sm_id]);
2051 #ifdef RTE_LIB_BITRATESTATS
2052 if (bitrate_enabled != 0 &&
2053 bitrate_lcore_id == rte_lcore_id()) {
2054 tics_current = rte_rdtsc();
2055 if (tics_current - tics_datum >= tics_per_1sec) {
2056 /* Periodic bitrate calculation */
2057 for (i = 0; i < cnt_ports; i++)
2058 rte_stats_bitrate_calc(bitrate_data,
2060 tics_datum = tics_current;
2064 #ifdef RTE_LIB_LATENCYSTATS
2065 if (latencystats_enabled != 0 &&
2066 latencystats_lcore_id == rte_lcore_id())
2067 rte_latencystats_update();
2070 } while (! fc->stopped);
2074 start_pkt_forward_on_core(void *fwd_arg)
2076 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
2077 cur_fwd_config.fwd_eng->packet_fwd);
2082 * Run the TXONLY packet forwarding engine to send a single burst of packets.
2083 * Used to start communication flows in network loopback test configurations.
2086 run_one_txonly_burst_on_core(void *fwd_arg)
2088 struct fwd_lcore *fwd_lc;
2089 struct fwd_lcore tmp_lcore;
2091 fwd_lc = (struct fwd_lcore *) fwd_arg;
2092 tmp_lcore = *fwd_lc;
2093 tmp_lcore.stopped = 1;
2094 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
2099 * Launch packet forwarding:
2100 * - Setup per-port forwarding context.
2101 * - launch logical cores with their forwarding configuration.
2104 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
2106 port_fwd_begin_t port_fwd_begin;
2111 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
2112 if (port_fwd_begin != NULL) {
2113 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2114 (*port_fwd_begin)(fwd_ports_ids[i]);
2116 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
2117 lc_id = fwd_lcores_cpuids[i];
2118 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
2119 fwd_lcores[i]->stopped = 0;
2120 diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
2121 fwd_lcores[i], lc_id);
2124 "launch lcore %u failed - diag=%d\n",
2131 * Launch packet forwarding configuration.
2134 start_packet_forwarding(int with_tx_first)
2136 port_fwd_begin_t port_fwd_begin;
2137 port_fwd_end_t port_fwd_end;
2140 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
2141 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
2143 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
2144 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
2146 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
2147 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
2148 (!nb_rxq || !nb_txq))
2149 rte_exit(EXIT_FAILURE,
2150 "Either rxq or txq are 0, cannot use %s fwd mode\n",
2151 cur_fwd_eng->fwd_mode_name);
2153 if (all_ports_started() == 0) {
2154 fprintf(stderr, "Not all ports were started\n");
2157 if (test_done == 0) {
2158 fprintf(stderr, "Packet forwarding already started\n");
2166 flush_fwd_rx_queues();
2168 pkt_fwd_config_display(&cur_fwd_config);
2169 rxtx_config_display();
2172 if (with_tx_first) {
2173 port_fwd_begin = tx_only_engine.port_fwd_begin;
2174 if (port_fwd_begin != NULL) {
2175 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2176 (*port_fwd_begin)(fwd_ports_ids[i]);
2178 while (with_tx_first--) {
2179 launch_packet_forwarding(
2180 run_one_txonly_burst_on_core);
2181 rte_eal_mp_wait_lcore();
2183 port_fwd_end = tx_only_engine.port_fwd_end;
2184 if (port_fwd_end != NULL) {
2185 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2186 (*port_fwd_end)(fwd_ports_ids[i]);
2189 launch_packet_forwarding(start_pkt_forward_on_core);
2193 stop_packet_forwarding(void)
2195 port_fwd_end_t port_fwd_end;
2201 fprintf(stderr, "Packet forwarding not started\n");
2204 printf("Telling cores to stop...");
2205 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
2206 fwd_lcores[lc_id]->stopped = 1;
2207 printf("\nWaiting for lcores to finish...\n");
2208 rte_eal_mp_wait_lcore();
2209 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
2210 if (port_fwd_end != NULL) {
2211 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
2212 pt_id = fwd_ports_ids[i];
2213 (*port_fwd_end)(pt_id);
2217 fwd_stats_display();
2219 printf("\nDone.\n");
2224 dev_set_link_up(portid_t pid)
2226 if (rte_eth_dev_set_link_up(pid) < 0)
2227 fprintf(stderr, "\nSet link up fail.\n");
2231 dev_set_link_down(portid_t pid)
2233 if (rte_eth_dev_set_link_down(pid) < 0)
2234 fprintf(stderr, "\nSet link down fail.\n");
2238 all_ports_started(void)
2241 struct rte_port *port;
2243 RTE_ETH_FOREACH_DEV(pi) {
2245 /* Check if there is a port which is not started */
2246 if ((port->port_status != RTE_PORT_STARTED) &&
2247 (port->slave_flag == 0))
2251 /* No port is not started */
2256 port_is_stopped(portid_t port_id)
2258 struct rte_port *port = &ports[port_id];
2260 if ((port->port_status != RTE_PORT_STOPPED) &&
2261 (port->slave_flag == 0))
2267 all_ports_stopped(void)
2271 RTE_ETH_FOREACH_DEV(pi) {
2272 if (!port_is_stopped(pi))
2280 port_is_started(portid_t port_id)
2282 if (port_id_is_invalid(port_id, ENABLED_WARN))
2285 if (ports[port_id].port_status != RTE_PORT_STARTED)
2291 /* Configure the Rx and Tx hairpin queues for the selected port. */
2293 setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi)
2296 struct rte_eth_hairpin_conf hairpin_conf = {
2301 struct rte_port *port = &ports[pi];
2302 uint16_t peer_rx_port = pi;
2303 uint16_t peer_tx_port = pi;
2304 uint32_t manual = 1;
2305 uint32_t tx_exp = hairpin_mode & 0x10;
2307 if (!(hairpin_mode & 0xf)) {
2311 } else if (hairpin_mode & 0x1) {
2312 peer_tx_port = rte_eth_find_next_owned_by(pi + 1,
2313 RTE_ETH_DEV_NO_OWNER);
2314 if (peer_tx_port >= RTE_MAX_ETHPORTS)
2315 peer_tx_port = rte_eth_find_next_owned_by(0,
2316 RTE_ETH_DEV_NO_OWNER);
2317 if (p_pi != RTE_MAX_ETHPORTS) {
2318 peer_rx_port = p_pi;
2322 /* Last port will be the peer RX port of the first. */
2323 RTE_ETH_FOREACH_DEV(next_pi)
2324 peer_rx_port = next_pi;
2327 } else if (hairpin_mode & 0x2) {
2329 peer_rx_port = p_pi;
2331 peer_rx_port = rte_eth_find_next_owned_by(pi + 1,
2332 RTE_ETH_DEV_NO_OWNER);
2333 if (peer_rx_port >= RTE_MAX_ETHPORTS)
2336 peer_tx_port = peer_rx_port;
2340 for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) {
2341 hairpin_conf.peers[0].port = peer_rx_port;
2342 hairpin_conf.peers[0].queue = i + nb_rxq;
2343 hairpin_conf.manual_bind = !!manual;
2344 hairpin_conf.tx_explicit = !!tx_exp;
2345 diag = rte_eth_tx_hairpin_queue_setup
2346 (pi, qi, nb_txd, &hairpin_conf);
2351 /* Fail to setup rx queue, return */
2352 if (rte_atomic16_cmpset(&(port->port_status),
2354 RTE_PORT_STOPPED) == 0)
2356 "Port %d can not be set back to stopped\n", pi);
2357 fprintf(stderr, "Fail to configure port %d hairpin queues\n",
2359 /* try to reconfigure queues next time */
2360 port->need_reconfig_queues = 1;
2363 for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) {
2364 hairpin_conf.peers[0].port = peer_tx_port;
2365 hairpin_conf.peers[0].queue = i + nb_txq;
2366 hairpin_conf.manual_bind = !!manual;
2367 hairpin_conf.tx_explicit = !!tx_exp;
2368 diag = rte_eth_rx_hairpin_queue_setup
2369 (pi, qi, nb_rxd, &hairpin_conf);
2374 /* Fail to setup rx queue, return */
2375 if (rte_atomic16_cmpset(&(port->port_status),
2377 RTE_PORT_STOPPED) == 0)
2379 "Port %d can not be set back to stopped\n", pi);
2380 fprintf(stderr, "Fail to configure port %d hairpin queues\n",
2382 /* try to reconfigure queues next time */
2383 port->need_reconfig_queues = 1;
2389 /* Configure the Rx with optional split. */
2391 rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
2392 uint16_t nb_rx_desc, unsigned int socket_id,
2393 struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
2395 union rte_eth_rxseg rx_useg[MAX_SEGS_BUFFER_SPLIT] = {};
2396 unsigned int i, mp_n;
2399 if (rx_pkt_nb_segs <= 1 ||
2400 (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) {
2401 rx_conf->rx_seg = NULL;
2402 rx_conf->rx_nseg = 0;
2403 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id,
2404 nb_rx_desc, socket_id,
2408 for (i = 0; i < rx_pkt_nb_segs; i++) {
2409 struct rte_eth_rxseg_split *rx_seg = &rx_useg[i].split;
2410 struct rte_mempool *mpx;
2412 * Use last valid pool for the segments with number
2413 * exceeding the pool index.
2415 mp_n = (i > mbuf_data_size_n) ? mbuf_data_size_n - 1 : i;
2416 mpx = mbuf_pool_find(socket_id, mp_n);
2417 /* Handle zero as mbuf data buffer size. */
2418 rx_seg->length = rx_pkt_seg_lengths[i] ?
2419 rx_pkt_seg_lengths[i] :
2420 mbuf_data_size[mp_n];
2421 rx_seg->offset = i < rx_pkt_nb_offs ?
2422 rx_pkt_seg_offsets[i] : 0;
2423 rx_seg->mp = mpx ? mpx : mp;
2425 rx_conf->rx_nseg = rx_pkt_nb_segs;
2426 rx_conf->rx_seg = rx_useg;
2427 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id, nb_rx_desc,
2428 socket_id, rx_conf, NULL);
2429 rx_conf->rx_seg = NULL;
2430 rx_conf->rx_nseg = 0;
2435 start_port(portid_t pid)
2437 int diag, need_check_link_status = -1;
2439 portid_t p_pi = RTE_MAX_ETHPORTS;
2440 portid_t pl[RTE_MAX_ETHPORTS];
2441 portid_t peer_pl[RTE_MAX_ETHPORTS];
2442 uint16_t cnt_pi = 0;
2443 uint16_t cfg_pi = 0;
2446 struct rte_port *port;
2447 struct rte_eth_hairpin_cap cap;
2449 if (port_id_is_invalid(pid, ENABLED_WARN))
2452 RTE_ETH_FOREACH_DEV(pi) {
2453 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2456 need_check_link_status = 0;
2458 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
2459 RTE_PORT_HANDLING) == 0) {
2460 fprintf(stderr, "Port %d is now not stopped\n", pi);
2464 if (port->need_reconfig > 0) {
2465 port->need_reconfig = 0;
2467 if (flow_isolate_all) {
2468 int ret = port_flow_isolate(pi, 1);
2471 "Failed to apply isolated mode on port %d\n",
2476 configure_rxtx_dump_callbacks(0);
2477 printf("Configuring Port %d (socket %u)\n", pi,
2479 if (nb_hairpinq > 0 &&
2480 rte_eth_dev_hairpin_capability_get(pi, &cap)) {
2482 "Port %d doesn't support hairpin queues\n",
2486 /* configure port */
2487 diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq,
2488 nb_txq + nb_hairpinq,
2491 if (rte_atomic16_cmpset(&(port->port_status),
2492 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2494 "Port %d can not be set back to stopped\n",
2496 fprintf(stderr, "Fail to configure port %d\n",
2498 /* try to reconfigure port next time */
2499 port->need_reconfig = 1;
2503 if (port->need_reconfig_queues > 0) {
2504 port->need_reconfig_queues = 0;
2505 /* setup tx queues */
2506 for (qi = 0; qi < nb_txq; qi++) {
2507 if ((numa_support) &&
2508 (txring_numa[pi] != NUMA_NO_CONFIG))
2509 diag = rte_eth_tx_queue_setup(pi, qi,
2510 port->nb_tx_desc[qi],
2512 &(port->tx_conf[qi]));
2514 diag = rte_eth_tx_queue_setup(pi, qi,
2515 port->nb_tx_desc[qi],
2517 &(port->tx_conf[qi]));
2522 /* Fail to setup tx queue, return */
2523 if (rte_atomic16_cmpset(&(port->port_status),
2525 RTE_PORT_STOPPED) == 0)
2527 "Port %d can not be set back to stopped\n",
2530 "Fail to configure port %d tx queues\n",
2532 /* try to reconfigure queues next time */
2533 port->need_reconfig_queues = 1;
2536 for (qi = 0; qi < nb_rxq; qi++) {
2537 /* setup rx queues */
2538 if ((numa_support) &&
2539 (rxring_numa[pi] != NUMA_NO_CONFIG)) {
2540 struct rte_mempool * mp =
2542 (rxring_numa[pi], 0);
2545 "Failed to setup RX queue: No mempool allocation on the socket %d\n",
2550 diag = rx_queue_setup(pi, qi,
2551 port->nb_rx_desc[qi],
2553 &(port->rx_conf[qi]),
2556 struct rte_mempool *mp =
2558 (port->socket_id, 0);
2561 "Failed to setup RX queue: No mempool allocation on the socket %d\n",
2565 diag = rx_queue_setup(pi, qi,
2566 port->nb_rx_desc[qi],
2568 &(port->rx_conf[qi]),
2574 /* Fail to setup rx queue, return */
2575 if (rte_atomic16_cmpset(&(port->port_status),
2577 RTE_PORT_STOPPED) == 0)
2579 "Port %d can not be set back to stopped\n",
2582 "Fail to configure port %d rx queues\n",
2584 /* try to reconfigure queues next time */
2585 port->need_reconfig_queues = 1;
2588 /* setup hairpin queues */
2589 if (setup_hairpin_queues(pi, p_pi, cnt_pi) != 0)
2592 configure_rxtx_dump_callbacks(verbose_level);
2594 diag = rte_eth_dev_set_ptypes(pi, RTE_PTYPE_UNKNOWN,
2598 "Port %d: Failed to disable Ptype parsing\n",
2606 diag = rte_eth_dev_start(pi);
2608 fprintf(stderr, "Fail to start port %d: %s\n",
2609 pi, rte_strerror(-diag));
2611 /* Fail to setup rx queue, return */
2612 if (rte_atomic16_cmpset(&(port->port_status),
2613 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2615 "Port %d can not be set back to stopped\n",
2620 if (rte_atomic16_cmpset(&(port->port_status),
2621 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2622 fprintf(stderr, "Port %d can not be set into started\n",
2625 if (eth_macaddr_get_print_err(pi, &port->eth_addr) == 0)
2626 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2627 port->eth_addr.addr_bytes[0],
2628 port->eth_addr.addr_bytes[1],
2629 port->eth_addr.addr_bytes[2],
2630 port->eth_addr.addr_bytes[3],
2631 port->eth_addr.addr_bytes[4],
2632 port->eth_addr.addr_bytes[5]);
2634 /* at least one port started, need checking link status */
2635 need_check_link_status = 1;
2640 if (need_check_link_status == 1 && !no_link_check)
2641 check_all_ports_link_status(RTE_PORT_ALL);
2642 else if (need_check_link_status == 0)
2643 fprintf(stderr, "Please stop the ports first\n");
2645 if (hairpin_mode & 0xf) {
2649 /* bind all started hairpin ports */
2650 for (i = 0; i < cfg_pi; i++) {
2652 /* bind current Tx to all peer Rx */
2653 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2654 RTE_MAX_ETHPORTS, 1);
2657 for (j = 0; j < peer_pi; j++) {
2658 if (!port_is_started(peer_pl[j]))
2660 diag = rte_eth_hairpin_bind(pi, peer_pl[j]);
2663 "Error during binding hairpin Tx port %u to %u: %s\n",
2665 rte_strerror(-diag));
2669 /* bind all peer Tx to current Rx */
2670 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2671 RTE_MAX_ETHPORTS, 0);
2674 for (j = 0; j < peer_pi; j++) {
2675 if (!port_is_started(peer_pl[j]))
2677 diag = rte_eth_hairpin_bind(peer_pl[j], pi);
2680 "Error during binding hairpin Tx port %u to %u: %s\n",
2682 rte_strerror(-diag));
2694 stop_port(portid_t pid)
2697 struct rte_port *port;
2698 int need_check_link_status = 0;
2699 portid_t peer_pl[RTE_MAX_ETHPORTS];
2702 if (port_id_is_invalid(pid, ENABLED_WARN))
2705 printf("Stopping ports...\n");
2707 RTE_ETH_FOREACH_DEV(pi) {
2708 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2711 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2713 "Please remove port %d from forwarding configuration.\n",
2718 if (port_is_bonding_slave(pi)) {
2720 "Please remove port %d from bonded device.\n",
2726 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
2727 RTE_PORT_HANDLING) == 0)
2730 if (hairpin_mode & 0xf) {
2733 rte_eth_hairpin_unbind(pi, RTE_MAX_ETHPORTS);
2734 /* unbind all peer Tx from current Rx */
2735 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2736 RTE_MAX_ETHPORTS, 0);
2739 for (j = 0; j < peer_pi; j++) {
2740 if (!port_is_started(peer_pl[j]))
2742 rte_eth_hairpin_unbind(peer_pl[j], pi);
2746 if (port->flow_list)
2747 port_flow_flush(pi);
2749 if (rte_eth_dev_stop(pi) != 0)
2750 RTE_LOG(ERR, EAL, "rte_eth_dev_stop failed for port %u\n",
2753 if (rte_atomic16_cmpset(&(port->port_status),
2754 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2755 fprintf(stderr, "Port %d can not be set into stopped\n",
2757 need_check_link_status = 1;
2759 if (need_check_link_status && !no_link_check)
2760 check_all_ports_link_status(RTE_PORT_ALL);
2766 remove_invalid_ports_in(portid_t *array, portid_t *total)
2769 portid_t new_total = 0;
2771 for (i = 0; i < *total; i++)
2772 if (!port_id_is_invalid(array[i], DISABLED_WARN)) {
2773 array[new_total] = array[i];
2780 remove_invalid_ports(void)
2782 remove_invalid_ports_in(ports_ids, &nb_ports);
2783 remove_invalid_ports_in(fwd_ports_ids, &nb_fwd_ports);
2784 nb_cfg_ports = nb_fwd_ports;
2788 close_port(portid_t pid)
2791 struct rte_port *port;
2793 if (port_id_is_invalid(pid, ENABLED_WARN))
2796 printf("Closing ports...\n");
2798 RTE_ETH_FOREACH_DEV(pi) {
2799 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2802 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2804 "Please remove port %d from forwarding configuration.\n",
2809 if (port_is_bonding_slave(pi)) {
2811 "Please remove port %d from bonded device.\n",
2817 if (rte_atomic16_cmpset(&(port->port_status),
2818 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2819 fprintf(stderr, "Port %d is already closed\n", pi);
2823 port_flow_flush(pi);
2824 rte_eth_dev_close(pi);
2827 remove_invalid_ports();
2832 reset_port(portid_t pid)
2836 struct rte_port *port;
2838 if (port_id_is_invalid(pid, ENABLED_WARN))
2841 if ((pid == (portid_t)RTE_PORT_ALL && !all_ports_stopped()) ||
2842 (pid != (portid_t)RTE_PORT_ALL && !port_is_stopped(pid))) {
2844 "Can not reset port(s), please stop port(s) first.\n");
2848 printf("Resetting ports...\n");
2850 RTE_ETH_FOREACH_DEV(pi) {
2851 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2854 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2856 "Please remove port %d from forwarding configuration.\n",
2861 if (port_is_bonding_slave(pi)) {
2863 "Please remove port %d from bonded device.\n",
2868 diag = rte_eth_dev_reset(pi);
2871 port->need_reconfig = 1;
2872 port->need_reconfig_queues = 1;
2874 fprintf(stderr, "Failed to reset port %d. diag=%d\n",
2883 attach_port(char *identifier)
2886 struct rte_dev_iterator iterator;
2888 printf("Attaching a new port...\n");
2890 if (identifier == NULL) {
2891 fprintf(stderr, "Invalid parameters are specified\n");
2895 if (rte_dev_probe(identifier) < 0) {
2896 TESTPMD_LOG(ERR, "Failed to attach port %s\n", identifier);
2900 /* first attach mode: event */
2901 if (setup_on_probe_event) {
2902 /* new ports are detected on RTE_ETH_EVENT_NEW event */
2903 for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++)
2904 if (ports[pi].port_status == RTE_PORT_HANDLING &&
2905 ports[pi].need_setup != 0)
2906 setup_attached_port(pi);
2910 /* second attach mode: iterator */
2911 RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator) {
2912 /* setup ports matching the devargs used for probing */
2913 if (port_is_forwarding(pi))
2914 continue; /* port was already attached before */
2915 setup_attached_port(pi);
2920 setup_attached_port(portid_t pi)
2922 unsigned int socket_id;
2925 socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2926 /* if socket_id is invalid, set to the first available socket. */
2927 if (check_socket_id(socket_id) < 0)
2928 socket_id = socket_ids[0];
2929 reconfig(pi, socket_id);
2930 ret = rte_eth_promiscuous_enable(pi);
2933 "Error during enabling promiscuous mode for port %u: %s - ignore\n",
2934 pi, rte_strerror(-ret));
2936 ports_ids[nb_ports++] = pi;
2937 fwd_ports_ids[nb_fwd_ports++] = pi;
2938 nb_cfg_ports = nb_fwd_ports;
2939 ports[pi].need_setup = 0;
2940 ports[pi].port_status = RTE_PORT_STOPPED;
2942 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2947 detach_device(struct rte_device *dev)
2952 fprintf(stderr, "Device already removed\n");
2956 printf("Removing a device...\n");
2958 RTE_ETH_FOREACH_DEV_OF(sibling, dev) {
2959 if (ports[sibling].port_status != RTE_PORT_CLOSED) {
2960 if (ports[sibling].port_status != RTE_PORT_STOPPED) {
2961 fprintf(stderr, "Port %u not stopped\n",
2965 port_flow_flush(sibling);
2969 if (rte_dev_remove(dev) < 0) {
2970 TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name);
2973 remove_invalid_ports();
2975 printf("Device is detached\n");
2976 printf("Now total ports is %d\n", nb_ports);
2982 detach_port_device(portid_t port_id)
2985 struct rte_eth_dev_info dev_info;
2987 if (port_id_is_invalid(port_id, ENABLED_WARN))
2990 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
2991 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
2992 fprintf(stderr, "Port not stopped\n");
2995 fprintf(stderr, "Port was not closed\n");
2998 ret = eth_dev_info_get_print_err(port_id, &dev_info);
3001 "Failed to get device info for port %d, not detaching\n",
3005 detach_device(dev_info.device);
3009 detach_devargs(char *identifier)
3011 struct rte_dev_iterator iterator;
3012 struct rte_devargs da;
3015 printf("Removing a device...\n");
3017 memset(&da, 0, sizeof(da));
3018 if (rte_devargs_parsef(&da, "%s", identifier)) {
3019 fprintf(stderr, "cannot parse identifier\n");
3023 RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) {
3024 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
3025 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
3026 fprintf(stderr, "Port %u not stopped\n",
3028 rte_eth_iterator_cleanup(&iterator);
3029 rte_devargs_reset(&da);
3032 port_flow_flush(port_id);
3036 if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) {
3037 TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n",
3038 da.name, da.bus->name);
3039 rte_devargs_reset(&da);
3043 remove_invalid_ports();
3045 printf("Device %s is detached\n", identifier);
3046 printf("Now total ports is %d\n", nb_ports);
3048 rte_devargs_reset(&da);
3059 stop_packet_forwarding();
3061 #ifndef RTE_EXEC_ENV_WINDOWS
3062 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3064 if (mp_alloc_type == MP_ALLOC_ANON)
3065 rte_mempool_mem_iter(mempools[i], dma_unmap_cb,
3070 if (ports != NULL) {
3072 RTE_ETH_FOREACH_DEV(pt_id) {
3073 printf("\nStopping port %d...\n", pt_id);
3077 RTE_ETH_FOREACH_DEV(pt_id) {
3078 printf("\nShutting down port %d...\n", pt_id);
3085 ret = rte_dev_event_monitor_stop();
3088 "fail to stop device event monitor.");
3092 ret = rte_dev_event_callback_unregister(NULL,
3093 dev_event_callback, NULL);
3096 "fail to unregister device event callback.\n");
3100 ret = rte_dev_hotplug_handle_disable();
3103 "fail to disable hotplug handling.\n");
3107 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3109 rte_mempool_free(mempools[i]);
3112 printf("\nBye...\n");
3115 typedef void (*cmd_func_t)(void);
3116 struct pmd_test_command {
3117 const char *cmd_name;
3118 cmd_func_t cmd_func;
3121 /* Check the link status of all ports in up to 9s, and print them finally */
3123 check_all_ports_link_status(uint32_t port_mask)
3125 #define CHECK_INTERVAL 100 /* 100ms */
3126 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
3128 uint8_t count, all_ports_up, print_flag = 0;
3129 struct rte_eth_link link;
3131 char link_status[RTE_ETH_LINK_MAX_STR_LEN];
3133 printf("Checking link statuses...\n");
3135 for (count = 0; count <= MAX_CHECK_TIME; count++) {
3137 RTE_ETH_FOREACH_DEV(portid) {
3138 if ((port_mask & (1 << portid)) == 0)
3140 memset(&link, 0, sizeof(link));
3141 ret = rte_eth_link_get_nowait(portid, &link);
3144 if (print_flag == 1)
3146 "Port %u link get failed: %s\n",
3147 portid, rte_strerror(-ret));
3150 /* print link status if flag set */
3151 if (print_flag == 1) {
3152 rte_eth_link_to_str(link_status,
3153 sizeof(link_status), &link);
3154 printf("Port %d %s\n", portid, link_status);
3157 /* clear all_ports_up flag if any link down */
3158 if (link.link_status == ETH_LINK_DOWN) {
3163 /* after finally printing all link status, get out */
3164 if (print_flag == 1)
3167 if (all_ports_up == 0) {
3169 rte_delay_ms(CHECK_INTERVAL);
3172 /* set the print_flag if all ports up or timeout */
3173 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
3183 rmv_port_callback(void *arg)
3185 int need_to_start = 0;
3186 int org_no_link_check = no_link_check;
3187 portid_t port_id = (intptr_t)arg;
3188 struct rte_eth_dev_info dev_info;
3191 RTE_ETH_VALID_PORTID_OR_RET(port_id);
3193 if (!test_done && port_is_forwarding(port_id)) {
3195 stop_packet_forwarding();
3199 no_link_check = org_no_link_check;
3201 ret = eth_dev_info_get_print_err(port_id, &dev_info);
3204 "Failed to get device info for port %d, not detaching\n",
3207 struct rte_device *device = dev_info.device;
3208 close_port(port_id);
3209 detach_device(device); /* might be already removed or have more ports */
3212 start_packet_forwarding(0);
3215 /* This function is used by the interrupt thread */
3217 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
3220 RTE_SET_USED(param);
3221 RTE_SET_USED(ret_param);
3223 if (type >= RTE_ETH_EVENT_MAX) {
3225 "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
3226 port_id, __func__, type);
3228 } else if (event_print_mask & (UINT32_C(1) << type)) {
3229 printf("\nPort %" PRIu16 ": %s event\n", port_id,
3230 eth_event_desc[type]);
3235 case RTE_ETH_EVENT_NEW:
3236 ports[port_id].need_setup = 1;
3237 ports[port_id].port_status = RTE_PORT_HANDLING;
3239 case RTE_ETH_EVENT_INTR_RMV:
3240 if (port_id_is_invalid(port_id, DISABLED_WARN))
3242 if (rte_eal_alarm_set(100000,
3243 rmv_port_callback, (void *)(intptr_t)port_id))
3245 "Could not set up deferred device removal\n");
3247 case RTE_ETH_EVENT_DESTROY:
3248 ports[port_id].port_status = RTE_PORT_CLOSED;
3249 printf("Port %u is closed\n", port_id);
3258 register_eth_event_callback(void)
3261 enum rte_eth_event_type event;
3263 for (event = RTE_ETH_EVENT_UNKNOWN;
3264 event < RTE_ETH_EVENT_MAX; event++) {
3265 ret = rte_eth_dev_callback_register(RTE_ETH_ALL,
3270 TESTPMD_LOG(ERR, "Failed to register callback for "
3271 "%s event\n", eth_event_desc[event]);
3279 /* This function is used by the interrupt thread */
3281 dev_event_callback(const char *device_name, enum rte_dev_event_type type,
3282 __rte_unused void *arg)
3287 if (type >= RTE_DEV_EVENT_MAX) {
3288 fprintf(stderr, "%s called upon invalid event %d\n",
3294 case RTE_DEV_EVENT_REMOVE:
3295 RTE_LOG(DEBUG, EAL, "The device: %s has been removed!\n",
3297 ret = rte_eth_dev_get_port_by_name(device_name, &port_id);
3299 RTE_LOG(ERR, EAL, "can not get port by device %s!\n",
3304 * Because the user's callback is invoked in eal interrupt
3305 * callback, the interrupt callback need to be finished before
3306 * it can be unregistered when detaching device. So finish
3307 * callback soon and use a deferred removal to detach device
3308 * is need. It is a workaround, once the device detaching be
3309 * moved into the eal in the future, the deferred removal could
3312 if (rte_eal_alarm_set(100000,
3313 rmv_port_callback, (void *)(intptr_t)port_id))
3315 "Could not set up deferred device removal\n");
3317 case RTE_DEV_EVENT_ADD:
3318 RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
3320 /* TODO: After finish kernel driver binding,
3321 * begin to attach port.
3330 rxtx_port_config(struct rte_port *port)
3335 for (qid = 0; qid < nb_rxq; qid++) {
3336 offloads = port->rx_conf[qid].offloads;
3337 port->rx_conf[qid] = port->dev_info.default_rxconf;
3339 port->rx_conf[qid].offloads = offloads;
3341 /* Check if any Rx parameters have been passed */
3342 if (rx_pthresh != RTE_PMD_PARAM_UNSET)
3343 port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
3345 if (rx_hthresh != RTE_PMD_PARAM_UNSET)
3346 port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
3348 if (rx_wthresh != RTE_PMD_PARAM_UNSET)
3349 port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
3351 if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
3352 port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
3354 if (rx_drop_en != RTE_PMD_PARAM_UNSET)
3355 port->rx_conf[qid].rx_drop_en = rx_drop_en;
3357 port->nb_rx_desc[qid] = nb_rxd;
3360 for (qid = 0; qid < nb_txq; qid++) {
3361 offloads = port->tx_conf[qid].offloads;
3362 port->tx_conf[qid] = port->dev_info.default_txconf;
3364 port->tx_conf[qid].offloads = offloads;
3366 /* Check if any Tx parameters have been passed */
3367 if (tx_pthresh != RTE_PMD_PARAM_UNSET)
3368 port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
3370 if (tx_hthresh != RTE_PMD_PARAM_UNSET)
3371 port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
3373 if (tx_wthresh != RTE_PMD_PARAM_UNSET)
3374 port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
3376 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
3377 port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
3379 if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
3380 port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
3382 port->nb_tx_desc[qid] = nb_txd;
3387 * Helper function to arrange max_rx_pktlen value and JUMBO_FRAME offload,
3388 * MTU is also aligned if JUMBO_FRAME offload is not set.
3390 * port->dev_info should be set before calling this function.
3392 * return 0 on success, negative on error
3395 update_jumbo_frame_offload(portid_t portid)
3397 struct rte_port *port = &ports[portid];
3398 uint32_t eth_overhead;
3399 uint64_t rx_offloads;
3403 /* Update the max_rx_pkt_len to have MTU as RTE_ETHER_MTU */
3404 if (port->dev_info.max_mtu != UINT16_MAX &&
3405 port->dev_info.max_rx_pktlen > port->dev_info.max_mtu)
3406 eth_overhead = port->dev_info.max_rx_pktlen -
3407 port->dev_info.max_mtu;
3409 eth_overhead = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
3411 rx_offloads = port->dev_conf.rxmode.offloads;
3413 /* Default config value is 0 to use PMD specific overhead */
3414 if (port->dev_conf.rxmode.max_rx_pkt_len == 0)
3415 port->dev_conf.rxmode.max_rx_pkt_len = RTE_ETHER_MTU + eth_overhead;
3417 if (port->dev_conf.rxmode.max_rx_pkt_len <= RTE_ETHER_MTU + eth_overhead) {
3418 rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3421 if ((port->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3423 "Frame size (%u) is not supported by port %u\n",
3424 port->dev_conf.rxmode.max_rx_pkt_len,
3428 rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3432 if (rx_offloads != port->dev_conf.rxmode.offloads) {
3435 port->dev_conf.rxmode.offloads = rx_offloads;
3437 /* Apply JUMBO_FRAME offload configuration to Rx queue(s) */
3438 for (qid = 0; qid < port->dev_info.nb_rx_queues; qid++) {
3440 port->rx_conf[qid].offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3442 port->rx_conf[qid].offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3446 /* If JUMBO_FRAME is set MTU conversion done by ethdev layer,
3447 * if unset do it here
3449 if ((rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3450 ret = rte_eth_dev_set_mtu(portid,
3451 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead);
3454 "Failed to set MTU to %u for port %u\n",
3455 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead,
3463 init_port_config(void)
3466 struct rte_port *port;
3469 RTE_ETH_FOREACH_DEV(pid) {
3471 port->dev_conf.fdir_conf = fdir_conf;
3473 ret = eth_dev_info_get_print_err(pid, &port->dev_info);
3478 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3479 port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
3480 rss_hf & port->dev_info.flow_type_rss_offloads;
3482 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3483 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
3486 if (port->dcb_flag == 0) {
3487 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
3488 port->dev_conf.rxmode.mq_mode =
3489 (enum rte_eth_rx_mq_mode)
3490 (rx_mq_mode & ETH_MQ_RX_RSS);
3492 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
3495 rxtx_port_config(port);
3497 ret = eth_macaddr_get_print_err(pid, &port->eth_addr);
3501 #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS
3502 rte_pmd_ixgbe_bypass_init(pid);
3505 if (lsc_interrupt && (*port->dev_info.dev_flags & RTE_ETH_DEV_INTR_LSC))
3506 port->dev_conf.intr_conf.lsc = 1;
3507 if (rmv_interrupt && (*port->dev_info.dev_flags & RTE_ETH_DEV_INTR_RMV))
3508 port->dev_conf.intr_conf.rmv = 1;
3512 void set_port_slave_flag(portid_t slave_pid)
3514 struct rte_port *port;
3516 port = &ports[slave_pid];
3517 port->slave_flag = 1;
3520 void clear_port_slave_flag(portid_t slave_pid)
3522 struct rte_port *port;
3524 port = &ports[slave_pid];
3525 port->slave_flag = 0;
3528 uint8_t port_is_bonding_slave(portid_t slave_pid)
3530 struct rte_port *port;
3531 struct rte_eth_dev_info dev_info;
3534 port = &ports[slave_pid];
3535 ret = eth_dev_info_get_print_err(slave_pid, &dev_info);
3538 "Failed to get device info for port id %d,"
3539 "cannot determine if the port is a bonded slave",
3543 if ((*dev_info.dev_flags & RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
3548 const uint16_t vlan_tags[] = {
3549 0, 1, 2, 3, 4, 5, 6, 7,
3550 8, 9, 10, 11, 12, 13, 14, 15,
3551 16, 17, 18, 19, 20, 21, 22, 23,
3552 24, 25, 26, 27, 28, 29, 30, 31
3556 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
3557 enum dcb_mode_enable dcb_mode,
3558 enum rte_eth_nb_tcs num_tcs,
3563 struct rte_eth_rss_conf rss_conf;
3566 * Builds up the correct configuration for dcb+vt based on the vlan tags array
3567 * given above, and the number of traffic classes available for use.
3569 if (dcb_mode == DCB_VT_ENABLED) {
3570 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
3571 ð_conf->rx_adv_conf.vmdq_dcb_conf;
3572 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
3573 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf;
3575 /* VMDQ+DCB RX and TX configurations */
3576 vmdq_rx_conf->enable_default_pool = 0;
3577 vmdq_rx_conf->default_pool = 0;
3578 vmdq_rx_conf->nb_queue_pools =
3579 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3580 vmdq_tx_conf->nb_queue_pools =
3581 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3583 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
3584 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
3585 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
3586 vmdq_rx_conf->pool_map[i].pools =
3587 1 << (i % vmdq_rx_conf->nb_queue_pools);
3589 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3590 vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
3591 vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
3594 /* set DCB mode of RX and TX of multiple queues */
3595 eth_conf->rxmode.mq_mode =
3596 (enum rte_eth_rx_mq_mode)
3597 (rx_mq_mode & ETH_MQ_RX_VMDQ_DCB);
3598 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
3600 struct rte_eth_dcb_rx_conf *rx_conf =
3601 ð_conf->rx_adv_conf.dcb_rx_conf;
3602 struct rte_eth_dcb_tx_conf *tx_conf =
3603 ð_conf->tx_adv_conf.dcb_tx_conf;
3605 memset(&rss_conf, 0, sizeof(struct rte_eth_rss_conf));
3607 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
3611 rx_conf->nb_tcs = num_tcs;
3612 tx_conf->nb_tcs = num_tcs;
3614 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3615 rx_conf->dcb_tc[i] = i % num_tcs;
3616 tx_conf->dcb_tc[i] = i % num_tcs;
3619 eth_conf->rxmode.mq_mode =
3620 (enum rte_eth_rx_mq_mode)
3621 (rx_mq_mode & ETH_MQ_RX_DCB_RSS);
3622 eth_conf->rx_adv_conf.rss_conf = rss_conf;
3623 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
3627 eth_conf->dcb_capability_en =
3628 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
3630 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
3636 init_port_dcb_config(portid_t pid,
3637 enum dcb_mode_enable dcb_mode,
3638 enum rte_eth_nb_tcs num_tcs,
3641 struct rte_eth_conf port_conf;
3642 struct rte_port *rte_port;
3646 rte_port = &ports[pid];
3648 memset(&port_conf, 0, sizeof(struct rte_eth_conf));
3650 port_conf.rxmode = rte_port->dev_conf.rxmode;
3651 port_conf.txmode = rte_port->dev_conf.txmode;
3653 /*set configuration of DCB in vt mode and DCB in non-vt mode*/
3654 retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
3657 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3659 /* re-configure the device . */
3660 retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
3664 retval = eth_dev_info_get_print_err(pid, &rte_port->dev_info);
3668 /* If dev_info.vmdq_pool_base is greater than 0,
3669 * the queue id of vmdq pools is started after pf queues.
3671 if (dcb_mode == DCB_VT_ENABLED &&
3672 rte_port->dev_info.vmdq_pool_base > 0) {
3674 "VMDQ_DCB multi-queue mode is nonsensical for port %d.\n",
3679 /* Assume the ports in testpmd have the same dcb capability
3680 * and has the same number of rxq and txq in dcb mode
3682 if (dcb_mode == DCB_VT_ENABLED) {
3683 if (rte_port->dev_info.max_vfs > 0) {
3684 nb_rxq = rte_port->dev_info.nb_rx_queues;
3685 nb_txq = rte_port->dev_info.nb_tx_queues;
3687 nb_rxq = rte_port->dev_info.max_rx_queues;
3688 nb_txq = rte_port->dev_info.max_tx_queues;
3691 /*if vt is disabled, use all pf queues */
3692 if (rte_port->dev_info.vmdq_pool_base == 0) {
3693 nb_rxq = rte_port->dev_info.max_rx_queues;
3694 nb_txq = rte_port->dev_info.max_tx_queues;
3696 nb_rxq = (queueid_t)num_tcs;
3697 nb_txq = (queueid_t)num_tcs;
3701 rx_free_thresh = 64;
3703 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
3705 rxtx_port_config(rte_port);
3707 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3708 for (i = 0; i < RTE_DIM(vlan_tags); i++)
3709 rx_vft_set(pid, vlan_tags[i], 1);
3711 retval = eth_macaddr_get_print_err(pid, &rte_port->eth_addr);
3715 rte_port->dcb_flag = 1;
3717 /* Enter DCB configuration status */
3728 /* Configuration of Ethernet ports. */
3729 ports = rte_zmalloc("testpmd: ports",
3730 sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
3731 RTE_CACHE_LINE_SIZE);
3732 if (ports == NULL) {
3733 rte_exit(EXIT_FAILURE,
3734 "rte_zmalloc(%d struct rte_port) failed\n",
3737 for (i = 0; i < RTE_MAX_ETHPORTS; i++)
3738 LIST_INIT(&ports[i].flow_tunnel_list);
3739 /* Initialize ports NUMA structures */
3740 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3741 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3742 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3756 const char clr[] = { 27, '[', '2', 'J', '\0' };
3757 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
3759 /* Clear screen and move to top left */
3760 printf("%s%s", clr, top_left);
3762 printf("\nPort statistics ====================================");
3763 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
3764 nic_stats_display(fwd_ports_ids[i]);
3770 signal_handler(int signum)
3772 if (signum == SIGINT || signum == SIGTERM) {
3773 fprintf(stderr, "\nSignal %d received, preparing to exit...\n",
3775 #ifdef RTE_LIB_PDUMP
3776 /* uninitialize packet capture framework */
3779 #ifdef RTE_LIB_LATENCYSTATS
3780 if (latencystats_enabled != 0)
3781 rte_latencystats_uninit();
3784 /* Set flag to indicate the force termination. */
3786 /* exit with the expected status */
3787 #ifndef RTE_EXEC_ENV_WINDOWS
3788 signal(signum, SIG_DFL);
3789 kill(getpid(), signum);
3795 main(int argc, char** argv)
3802 signal(SIGINT, signal_handler);
3803 signal(SIGTERM, signal_handler);
3805 testpmd_logtype = rte_log_register("testpmd");
3806 if (testpmd_logtype < 0)
3807 rte_exit(EXIT_FAILURE, "Cannot register log type");
3808 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3810 diag = rte_eal_init(argc, argv);
3812 rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n",
3813 rte_strerror(rte_errno));
3815 if (rte_eal_process_type() == RTE_PROC_SECONDARY)
3816 rte_exit(EXIT_FAILURE,
3817 "Secondary process type not supported.\n");
3819 ret = register_eth_event_callback();
3821 rte_exit(EXIT_FAILURE, "Cannot register for ethdev events");
3823 #ifdef RTE_LIB_PDUMP
3824 /* initialize packet capture framework */
3829 RTE_ETH_FOREACH_DEV(port_id) {
3830 ports_ids[count] = port_id;
3833 nb_ports = (portid_t) count;
3835 TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3837 /* allocate port structures, and init them */
3840 set_def_fwd_config();
3842 rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n"
3843 "Check the core mask argument\n");
3845 /* Bitrate/latency stats disabled by default */
3846 #ifdef RTE_LIB_BITRATESTATS
3847 bitrate_enabled = 0;
3849 #ifdef RTE_LIB_LATENCYSTATS
3850 latencystats_enabled = 0;
3853 /* on FreeBSD, mlockall() is disabled by default */
3854 #ifdef RTE_EXEC_ENV_FREEBSD
3863 launch_args_parse(argc, argv);
3865 #ifndef RTE_EXEC_ENV_WINDOWS
3866 if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3867 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3872 if (tx_first && interactive)
3873 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3874 "interactive mode.\n");
3876 if (tx_first && lsc_interrupt) {
3878 "Warning: lsc_interrupt needs to be off when using tx_first. Disabling.\n");
3882 if (!nb_rxq && !nb_txq)
3884 "Warning: Either rx or tx queues should be non-zero\n");
3886 if (nb_rxq > 1 && nb_rxq > nb_txq)
3888 "Warning: nb_rxq=%d enables RSS configuration, but nb_txq=%d will prevent to fully test it.\n",
3894 ret = rte_dev_hotplug_handle_enable();
3897 "fail to enable hotplug handling.");
3901 ret = rte_dev_event_monitor_start();
3904 "fail to start device event monitoring.");
3908 ret = rte_dev_event_callback_register(NULL,
3909 dev_event_callback, NULL);
3912 "fail to register device event callback\n");
3917 if (!no_device_start && start_port(RTE_PORT_ALL) != 0)
3918 rte_exit(EXIT_FAILURE, "Start ports failed\n");
3920 /* set all ports to promiscuous mode by default */
3921 RTE_ETH_FOREACH_DEV(port_id) {
3922 ret = rte_eth_promiscuous_enable(port_id);
3925 "Error during enabling promiscuous mode for port %u: %s - ignore\n",
3926 port_id, rte_strerror(-ret));
3929 /* Init metrics library */
3930 rte_metrics_init(rte_socket_id());
3932 #ifdef RTE_LIB_LATENCYSTATS
3933 if (latencystats_enabled != 0) {
3934 int ret = rte_latencystats_init(1, NULL);
3937 "Warning: latencystats init() returned error %d\n",
3939 fprintf(stderr, "Latencystats running on lcore %d\n",
3940 latencystats_lcore_id);
3944 /* Setup bitrate stats */
3945 #ifdef RTE_LIB_BITRATESTATS
3946 if (bitrate_enabled != 0) {
3947 bitrate_data = rte_stats_bitrate_create();
3948 if (bitrate_data == NULL)
3949 rte_exit(EXIT_FAILURE,
3950 "Could not allocate bitrate data.\n");
3951 rte_stats_bitrate_reg(bitrate_data);
3955 #ifdef RTE_LIB_CMDLINE
3956 if (strlen(cmdline_filename) != 0)
3957 cmdline_read_from_file(cmdline_filename);
3959 if (interactive == 1) {
3961 printf("Start automatic packet forwarding\n");
3962 start_packet_forwarding(0);
3974 printf("No commandline core given, start packet forwarding\n");
3975 start_packet_forwarding(tx_first);
3976 if (stats_period != 0) {
3977 uint64_t prev_time = 0, cur_time, diff_time = 0;
3978 uint64_t timer_period;
3980 /* Convert to number of cycles */
3981 timer_period = stats_period * rte_get_timer_hz();
3983 while (f_quit == 0) {
3984 cur_time = rte_get_timer_cycles();
3985 diff_time += cur_time - prev_time;
3987 if (diff_time >= timer_period) {
3989 /* Reset the timer */
3992 /* Sleep to avoid unnecessary checks */
3993 prev_time = cur_time;
3994 rte_delay_us_sleep(US_PER_S);
3998 printf("Press enter to exit\n");
3999 rc = read(0, &c, 1);
4005 ret = rte_eal_cleanup();
4007 rte_exit(EXIT_FAILURE,
4008 "EAL cleanup failed: %s\n", strerror(-ret));
4010 return EXIT_SUCCESS;