1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2017 Intel Corporation
13 #include <sys/types.h>
17 #include <sys/queue.h>
24 #include <rte_common.h>
25 #include <rte_errno.h>
26 #include <rte_byteorder.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>
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>
42 #include <rte_mbuf_pool_ops.h>
43 #include <rte_interrupts.h>
45 #include <rte_ether.h>
46 #include <rte_ethdev.h>
48 #include <rte_string_fns.h>
50 #include <rte_pmd_ixgbe.h>
53 #include <rte_pdump.h>
56 #include <rte_metrics.h>
57 #ifdef RTE_LIB_BITRATESTATS
58 #include <rte_bitrate.h>
60 #ifdef RTE_LIB_LATENCYSTATS
61 #include <rte_latencystats.h>
67 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */
68 #define HUGE_FLAG (0x40000)
70 #define HUGE_FLAG MAP_HUGETLB
73 #ifndef MAP_HUGE_SHIFT
74 /* older kernels (or FreeBSD) will not have this define */
75 #define HUGE_SHIFT (26)
77 #define HUGE_SHIFT MAP_HUGE_SHIFT
80 #define EXTMEM_HEAP_NAME "extmem"
81 #define EXTBUF_ZONE_SIZE RTE_PGSIZE_2M
83 uint16_t verbose_level = 0; /**< Silent by default. */
84 int testpmd_logtype; /**< Log type for testpmd logs */
86 /* use main core for command line ? */
87 uint8_t interactive = 0;
88 uint8_t auto_start = 0;
90 char cmdline_filename[PATH_MAX] = {0};
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.
99 uint8_t numa_support = 1; /**< numa enabled by default */
102 * In UMA mode,all memory is allocated from socket 0 if --socket-num is
105 uint8_t socket_num = UMA_NO_CONFIG;
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
114 uint8_t mp_alloc_type = MP_ALLOC_NATIVE;
117 * Store specified sockets on which memory pool to be used by ports
120 uint8_t port_numa[RTE_MAX_ETHPORTS];
123 * Store specified sockets on which RX ring to be used by ports
126 uint8_t rxring_numa[RTE_MAX_ETHPORTS];
129 * Store specified sockets on which TX ring to be used by ports
132 uint8_t txring_numa[RTE_MAX_ETHPORTS];
135 * Record the Ethernet address of peer target ports to which packets are
137 * Must be instantiated with the ethernet addresses of peer traffic generator
140 struct rte_ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
141 portid_t nb_peer_eth_addrs = 0;
144 * Probed Target Environment.
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. */
151 portid_t ports_ids[RTE_MAX_ETHPORTS]; /**< Store all port ids. */
154 * Test Forwarding Configuration.
155 * nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
156 * nb_fwd_ports <= nb_cfg_ports <= nb_ports
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. */
163 unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE]; /**< CPU ids configuration. */
164 portid_t fwd_ports_ids[RTE_MAX_ETHPORTS]; /**< Port ids configuration. */
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). */
170 * Forwarding engines.
172 struct fwd_engine * fwd_engines[] = {
182 &five_tuple_swap_fwd_engine,
183 #ifdef RTE_LIBRTE_IEEE1588
184 &ieee1588_fwd_engine,
189 struct rte_mempool *mempools[RTE_MAX_NUMA_NODES * MAX_SEGS_BUFFER_SPLIT];
190 uint16_t mempool_flags;
192 struct fwd_config cur_fwd_config;
193 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
194 uint32_t retry_enabled;
195 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
196 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
198 uint32_t mbuf_data_size_n = 1; /* Number of specified mbuf sizes. */
199 uint16_t mbuf_data_size[MAX_SEGS_BUFFER_SPLIT] = {
200 DEFAULT_MBUF_DATA_SIZE
201 }; /**< Mbuf data space size. */
202 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if
203 * specified on command-line. */
204 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
207 * In container, it cannot terminate the process which running with 'stats-period'
208 * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
213 * Configuration of packet segments used to scatter received packets
214 * if some of split features is configured.
216 uint16_t rx_pkt_seg_lengths[MAX_SEGS_BUFFER_SPLIT];
217 uint8_t rx_pkt_nb_segs; /**< Number of segments to split */
218 uint16_t rx_pkt_seg_offsets[MAX_SEGS_BUFFER_SPLIT];
219 uint8_t rx_pkt_nb_offs; /**< Number of specified offsets */
222 * Configuration of packet segments used by the "txonly" processing engine.
224 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
225 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
226 TXONLY_DEF_PACKET_LEN,
228 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
230 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
231 /**< Split policy for packets to TX. */
233 uint8_t txonly_multi_flow;
234 /**< Whether multiple flows are generated in TXONLY mode. */
236 uint32_t tx_pkt_times_inter;
237 /**< Timings for send scheduling in TXONLY mode, time between bursts. */
239 uint32_t tx_pkt_times_intra;
240 /**< Timings for send scheduling in TXONLY mode, time between packets. */
242 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
243 uint16_t nb_pkt_flowgen_clones; /**< Number of Tx packet clones to send in flowgen mode. */
244 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
246 /* current configuration is in DCB or not,0 means it is not in DCB mode */
247 uint8_t dcb_config = 0;
249 /* Whether the dcb is in testing status */
250 uint8_t dcb_test = 0;
253 * Configurable number of RX/TX queues.
255 queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */
256 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
257 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
260 * Configurable number of RX/TX ring descriptors.
261 * Defaults are supplied by drivers via ethdev.
263 #define RTE_TEST_RX_DESC_DEFAULT 0
264 #define RTE_TEST_TX_DESC_DEFAULT 0
265 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
266 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
268 #define RTE_PMD_PARAM_UNSET -1
270 * Configurable values of RX and TX ring threshold registers.
273 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
274 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
275 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
277 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
278 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
279 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
282 * Configurable value of RX free threshold.
284 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
287 * Configurable value of RX drop enable.
289 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
292 * Configurable value of TX free threshold.
294 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
297 * Configurable value of TX RS bit threshold.
299 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
302 * Configurable value of buffered packets before sending.
304 uint16_t noisy_tx_sw_bufsz;
307 * Configurable value of packet buffer timeout.
309 uint16_t noisy_tx_sw_buf_flush_time;
312 * Configurable value for size of VNF internal memory area
313 * used for simulating noisy neighbour behaviour
315 uint64_t noisy_lkup_mem_sz;
318 * Configurable value of number of random writes done in
319 * VNF simulation memory area.
321 uint64_t noisy_lkup_num_writes;
324 * Configurable value of number of random reads done in
325 * VNF simulation memory area.
327 uint64_t noisy_lkup_num_reads;
330 * Configurable value of number of random reads/writes done in
331 * VNF simulation memory area.
333 uint64_t noisy_lkup_num_reads_writes;
336 * Receive Side Scaling (RSS) configuration.
338 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
341 * Port topology configuration
343 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
346 * Avoids to flush all the RX streams before starts forwarding.
348 uint8_t no_flush_rx = 0; /* flush by default */
351 * Flow API isolated mode.
353 uint8_t flow_isolate_all;
356 * Avoids to check link status when starting/stopping a port.
358 uint8_t no_link_check = 0; /* check by default */
361 * Don't automatically start all ports in interactive mode.
363 uint8_t no_device_start = 0;
366 * Enable link status change notification
368 uint8_t lsc_interrupt = 1; /* enabled by default */
371 * Enable device removal notification.
373 uint8_t rmv_interrupt = 1; /* enabled by default */
375 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
377 /* After attach, port setup is called on event or by iterator */
378 bool setup_on_probe_event = true;
380 /* Clear ptypes on port initialization. */
381 uint8_t clear_ptypes = true;
383 /* Hairpin ports configuration mode. */
384 uint16_t hairpin_mode;
386 /* Pretty printing of ethdev events */
387 static const char * const eth_event_desc[] = {
388 [RTE_ETH_EVENT_UNKNOWN] = "unknown",
389 [RTE_ETH_EVENT_INTR_LSC] = "link state change",
390 [RTE_ETH_EVENT_QUEUE_STATE] = "queue state",
391 [RTE_ETH_EVENT_INTR_RESET] = "reset",
392 [RTE_ETH_EVENT_VF_MBOX] = "VF mbox",
393 [RTE_ETH_EVENT_IPSEC] = "IPsec",
394 [RTE_ETH_EVENT_MACSEC] = "MACsec",
395 [RTE_ETH_EVENT_INTR_RMV] = "device removal",
396 [RTE_ETH_EVENT_NEW] = "device probed",
397 [RTE_ETH_EVENT_DESTROY] = "device released",
398 [RTE_ETH_EVENT_FLOW_AGED] = "flow aged",
399 [RTE_ETH_EVENT_MAX] = NULL,
403 * Display or mask ether events
404 * Default to all events except VF_MBOX
406 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
407 (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
408 (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
409 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
410 (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
411 (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
412 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV) |
413 (UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED);
415 * Decide if all memory are locked for performance.
420 * NIC bypass mode configuration options.
423 #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS
424 /* The NIC bypass watchdog timeout. */
425 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
429 #ifdef RTE_LIB_LATENCYSTATS
432 * Set when latency stats is enabled in the commandline
434 uint8_t latencystats_enabled;
437 * Lcore ID to serive latency statistics.
439 lcoreid_t latencystats_lcore_id = -1;
444 * Ethernet device configuration.
446 struct rte_eth_rxmode rx_mode = {
447 /* Default maximum frame length.
448 * Zero is converted to "RTE_ETHER_MTU + PMD Ethernet overhead"
454 struct rte_eth_txmode tx_mode = {
455 .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
458 struct rte_fdir_conf fdir_conf = {
459 .mode = RTE_FDIR_MODE_NONE,
460 .pballoc = RTE_FDIR_PBALLOC_64K,
461 .status = RTE_FDIR_REPORT_STATUS,
463 .vlan_tci_mask = 0xFFEF,
465 .src_ip = 0xFFFFFFFF,
466 .dst_ip = 0xFFFFFFFF,
469 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
470 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
472 .src_port_mask = 0xFFFF,
473 .dst_port_mask = 0xFFFF,
474 .mac_addr_byte_mask = 0xFF,
475 .tunnel_type_mask = 1,
476 .tunnel_id_mask = 0xFFFFFFFF,
481 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
484 * Display zero values by default for xstats
486 uint8_t xstats_hide_zero;
489 * Measure of CPU cycles disabled by default
491 uint8_t record_core_cycles;
494 * Display of RX and TX bursts disabled by default
496 uint8_t record_burst_stats;
498 unsigned int num_sockets = 0;
499 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
501 #ifdef RTE_LIB_BITRATESTATS
502 /* Bitrate statistics */
503 struct rte_stats_bitrates *bitrate_data;
504 lcoreid_t bitrate_lcore_id;
505 uint8_t bitrate_enabled;
508 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
509 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
512 * hexadecimal bitmask of RX mq mode can be enabled.
514 enum rte_eth_rx_mq_mode rx_mq_mode = ETH_MQ_RX_VMDQ_DCB_RSS;
516 /* Forward function declarations */
517 static void setup_attached_port(portid_t pi);
518 static void check_all_ports_link_status(uint32_t port_mask);
519 static int eth_event_callback(portid_t port_id,
520 enum rte_eth_event_type type,
521 void *param, void *ret_param);
522 static void dev_event_callback(const char *device_name,
523 enum rte_dev_event_type type,
527 * Check if all the ports are started.
528 * If yes, return positive value. If not, return zero.
530 static int all_ports_started(void);
532 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
533 uint16_t gso_max_segment_size = RTE_ETHER_MAX_LEN - RTE_ETHER_CRC_LEN;
535 /* Holds the registered mbuf dynamic flags names. */
536 char dynf_names[64][RTE_MBUF_DYN_NAMESIZE];
539 * Helper function to check if socket is already discovered.
540 * If yes, return positive value. If not, return zero.
543 new_socket_id(unsigned int socket_id)
547 for (i = 0; i < num_sockets; i++) {
548 if (socket_ids[i] == socket_id)
555 * Setup default configuration.
558 set_default_fwd_lcores_config(void)
562 unsigned int sock_num;
565 for (i = 0; i < RTE_MAX_LCORE; i++) {
566 if (!rte_lcore_is_enabled(i))
568 sock_num = rte_lcore_to_socket_id(i);
569 if (new_socket_id(sock_num)) {
570 if (num_sockets >= RTE_MAX_NUMA_NODES) {
571 rte_exit(EXIT_FAILURE,
572 "Total sockets greater than %u\n",
575 socket_ids[num_sockets++] = sock_num;
577 if (i == rte_get_main_lcore())
579 fwd_lcores_cpuids[nb_lc++] = i;
581 nb_lcores = (lcoreid_t) nb_lc;
582 nb_cfg_lcores = nb_lcores;
587 set_def_peer_eth_addrs(void)
591 for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
592 peer_eth_addrs[i].addr_bytes[0] = RTE_ETHER_LOCAL_ADMIN_ADDR;
593 peer_eth_addrs[i].addr_bytes[5] = i;
598 set_default_fwd_ports_config(void)
603 RTE_ETH_FOREACH_DEV(pt_id) {
604 fwd_ports_ids[i++] = pt_id;
606 /* Update sockets info according to the attached device */
607 int socket_id = rte_eth_dev_socket_id(pt_id);
608 if (socket_id >= 0 && new_socket_id(socket_id)) {
609 if (num_sockets >= RTE_MAX_NUMA_NODES) {
610 rte_exit(EXIT_FAILURE,
611 "Total sockets greater than %u\n",
614 socket_ids[num_sockets++] = socket_id;
618 nb_cfg_ports = nb_ports;
619 nb_fwd_ports = nb_ports;
623 set_def_fwd_config(void)
625 set_default_fwd_lcores_config();
626 set_def_peer_eth_addrs();
627 set_default_fwd_ports_config();
630 /* extremely pessimistic estimation of memory required to create a mempool */
632 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
634 unsigned int n_pages, mbuf_per_pg, leftover;
635 uint64_t total_mem, mbuf_mem, obj_sz;
637 /* there is no good way to predict how much space the mempool will
638 * occupy because it will allocate chunks on the fly, and some of those
639 * will come from default DPDK memory while some will come from our
640 * external memory, so just assume 128MB will be enough for everyone.
642 uint64_t hdr_mem = 128 << 20;
644 /* account for possible non-contiguousness */
645 obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL);
647 TESTPMD_LOG(ERR, "Object size is bigger than page size\n");
651 mbuf_per_pg = pgsz / obj_sz;
652 leftover = (nb_mbufs % mbuf_per_pg) > 0;
653 n_pages = (nb_mbufs / mbuf_per_pg) + leftover;
655 mbuf_mem = n_pages * pgsz;
657 total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz);
659 if (total_mem > SIZE_MAX) {
660 TESTPMD_LOG(ERR, "Memory size too big\n");
663 *out = (size_t)total_mem;
669 pagesz_flags(uint64_t page_sz)
671 /* as per mmap() manpage, all page sizes are log2 of page size
672 * shifted by MAP_HUGE_SHIFT
674 int log2 = rte_log2_u64(page_sz);
676 return (log2 << HUGE_SHIFT);
680 alloc_mem(size_t memsz, size_t pgsz, bool huge)
685 /* allocate anonymous hugepages */
686 flags = MAP_ANONYMOUS | MAP_PRIVATE;
688 flags |= HUGE_FLAG | pagesz_flags(pgsz);
690 addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0);
691 if (addr == MAP_FAILED)
697 struct extmem_param {
701 rte_iova_t *iova_table;
702 unsigned int iova_table_len;
706 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param,
709 uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */
710 RTE_PGSIZE_16M, RTE_PGSIZE_16G}; /* POWER */
711 unsigned int cur_page, n_pages, pgsz_idx;
712 size_t mem_sz, cur_pgsz;
713 rte_iova_t *iovas = NULL;
717 for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) {
718 /* skip anything that is too big */
719 if (pgsizes[pgsz_idx] > SIZE_MAX)
722 cur_pgsz = pgsizes[pgsz_idx];
724 /* if we were told not to allocate hugepages, override */
726 cur_pgsz = sysconf(_SC_PAGESIZE);
728 ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz);
730 TESTPMD_LOG(ERR, "Cannot calculate memory size\n");
734 /* allocate our memory */
735 addr = alloc_mem(mem_sz, cur_pgsz, huge);
737 /* if we couldn't allocate memory with a specified page size,
738 * that doesn't mean we can't do it with other page sizes, so
744 /* store IOVA addresses for every page in this memory area */
745 n_pages = mem_sz / cur_pgsz;
747 iovas = malloc(sizeof(*iovas) * n_pages);
750 TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n");
753 /* lock memory if it's not huge pages */
757 /* populate IOVA addresses */
758 for (cur_page = 0; cur_page < n_pages; cur_page++) {
763 offset = cur_pgsz * cur_page;
764 cur = RTE_PTR_ADD(addr, offset);
766 /* touch the page before getting its IOVA */
767 *(volatile char *)cur = 0;
769 iova = rte_mem_virt2iova(cur);
771 iovas[cur_page] = iova;
776 /* if we couldn't allocate anything */
782 param->pgsz = cur_pgsz;
783 param->iova_table = iovas;
784 param->iova_table_len = n_pages;
791 munmap(addr, mem_sz);
797 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge)
799 struct extmem_param param;
802 memset(¶m, 0, sizeof(param));
804 /* check if our heap exists */
805 socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
807 /* create our heap */
808 ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME);
810 TESTPMD_LOG(ERR, "Cannot create heap\n");
815 ret = create_extmem(nb_mbufs, mbuf_sz, ¶m, huge);
817 TESTPMD_LOG(ERR, "Cannot create memory area\n");
821 /* we now have a valid memory area, so add it to heap */
822 ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME,
823 param.addr, param.len, param.iova_table,
824 param.iova_table_len, param.pgsz);
826 /* when using VFIO, memory is automatically mapped for DMA by EAL */
828 /* not needed any more */
829 free(param.iova_table);
832 TESTPMD_LOG(ERR, "Cannot add memory to heap\n");
833 munmap(param.addr, param.len);
839 TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n",
845 dma_unmap_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused,
846 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused)
851 RTE_ETH_FOREACH_DEV(pid) {
852 struct rte_eth_dev *dev =
853 &rte_eth_devices[pid];
855 ret = rte_dev_dma_unmap(dev->device, memhdr->addr, 0,
859 "unable to DMA unmap addr 0x%p "
861 memhdr->addr, dev->data->name);
864 ret = rte_extmem_unregister(memhdr->addr, memhdr->len);
867 "unable to un-register addr 0x%p\n", memhdr->addr);
872 dma_map_cb(struct rte_mempool *mp __rte_unused, void *opaque __rte_unused,
873 struct rte_mempool_memhdr *memhdr, unsigned mem_idx __rte_unused)
876 size_t page_size = sysconf(_SC_PAGESIZE);
879 ret = rte_extmem_register(memhdr->addr, memhdr->len, NULL, 0,
883 "unable to register addr 0x%p\n", memhdr->addr);
886 RTE_ETH_FOREACH_DEV(pid) {
887 struct rte_eth_dev *dev =
888 &rte_eth_devices[pid];
890 ret = rte_dev_dma_map(dev->device, memhdr->addr, 0,
894 "unable to DMA map addr 0x%p "
896 memhdr->addr, dev->data->name);
902 setup_extbuf(uint32_t nb_mbufs, uint16_t mbuf_sz, unsigned int socket_id,
903 char *pool_name, struct rte_pktmbuf_extmem **ext_mem)
905 struct rte_pktmbuf_extmem *xmem;
906 unsigned int ext_num, zone_num, elt_num;
909 elt_size = RTE_ALIGN_CEIL(mbuf_sz, RTE_CACHE_LINE_SIZE);
910 elt_num = EXTBUF_ZONE_SIZE / elt_size;
911 zone_num = (nb_mbufs + elt_num - 1) / elt_num;
913 xmem = malloc(sizeof(struct rte_pktmbuf_extmem) * zone_num);
915 TESTPMD_LOG(ERR, "Cannot allocate memory for "
916 "external buffer descriptors\n");
920 for (ext_num = 0; ext_num < zone_num; ext_num++) {
921 struct rte_pktmbuf_extmem *xseg = xmem + ext_num;
922 const struct rte_memzone *mz;
923 char mz_name[RTE_MEMZONE_NAMESIZE];
926 ret = snprintf(mz_name, sizeof(mz_name),
927 RTE_MEMPOOL_MZ_FORMAT "_xb_%u", pool_name, ext_num);
928 if (ret < 0 || ret >= (int)sizeof(mz_name)) {
929 errno = ENAMETOOLONG;
933 mz = rte_memzone_reserve_aligned(mz_name, EXTBUF_ZONE_SIZE,
935 RTE_MEMZONE_IOVA_CONTIG |
937 RTE_MEMZONE_SIZE_HINT_ONLY,
941 * The caller exits on external buffer creation
942 * error, so there is no need to free memzones.
948 xseg->buf_ptr = mz->addr;
949 xseg->buf_iova = mz->iova;
950 xseg->buf_len = EXTBUF_ZONE_SIZE;
951 xseg->elt_size = elt_size;
953 if (ext_num == 0 && xmem != NULL) {
962 * Configuration initialisation done once at init time.
964 static struct rte_mempool *
965 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
966 unsigned int socket_id, uint16_t size_idx)
968 char pool_name[RTE_MEMPOOL_NAMESIZE];
969 struct rte_mempool *rte_mp = NULL;
972 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
973 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name), size_idx);
976 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
977 pool_name, nb_mbuf, mbuf_seg_size, socket_id);
979 switch (mp_alloc_type) {
980 case MP_ALLOC_NATIVE:
982 /* wrapper to rte_mempool_create() */
983 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
984 rte_mbuf_best_mempool_ops());
985 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
986 mb_mempool_cache, 0, mbuf_seg_size, socket_id);
991 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
992 mb_size, (unsigned int) mb_mempool_cache,
993 sizeof(struct rte_pktmbuf_pool_private),
994 socket_id, mempool_flags);
998 if (rte_mempool_populate_anon(rte_mp) == 0) {
999 rte_mempool_free(rte_mp);
1003 rte_pktmbuf_pool_init(rte_mp, NULL);
1004 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
1005 rte_mempool_mem_iter(rte_mp, dma_map_cb, NULL);
1009 case MP_ALLOC_XMEM_HUGE:
1012 bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE;
1014 if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0)
1015 rte_exit(EXIT_FAILURE, "Could not create external memory\n");
1018 rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
1019 if (heap_socket < 0)
1020 rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n");
1022 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
1023 rte_mbuf_best_mempool_ops());
1024 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
1025 mb_mempool_cache, 0, mbuf_seg_size,
1031 struct rte_pktmbuf_extmem *ext_mem;
1032 unsigned int ext_num;
1034 ext_num = setup_extbuf(nb_mbuf, mbuf_seg_size,
1035 socket_id, pool_name, &ext_mem);
1037 rte_exit(EXIT_FAILURE,
1038 "Can't create pinned data buffers\n");
1040 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
1041 rte_mbuf_best_mempool_ops());
1042 rte_mp = rte_pktmbuf_pool_create_extbuf
1043 (pool_name, nb_mbuf, mb_mempool_cache,
1044 0, mbuf_seg_size, socket_id,
1051 rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
1056 if (rte_mp == NULL) {
1057 rte_exit(EXIT_FAILURE,
1058 "Creation of mbuf pool for socket %u failed: %s\n",
1059 socket_id, rte_strerror(rte_errno));
1060 } else if (verbose_level > 0) {
1061 rte_mempool_dump(stdout, rte_mp);
1067 * Check given socket id is valid or not with NUMA mode,
1068 * if valid, return 0, else return -1
1071 check_socket_id(const unsigned int socket_id)
1073 static int warning_once = 0;
1075 if (new_socket_id(socket_id)) {
1076 if (!warning_once && numa_support)
1077 printf("Warning: NUMA should be configured manually by"
1078 " using --port-numa-config and"
1079 " --ring-numa-config parameters along with"
1088 * Get the allowed maximum number of RX queues.
1089 * *pid return the port id which has minimal value of
1090 * max_rx_queues in all ports.
1093 get_allowed_max_nb_rxq(portid_t *pid)
1095 queueid_t allowed_max_rxq = RTE_MAX_QUEUES_PER_PORT;
1096 bool max_rxq_valid = false;
1098 struct rte_eth_dev_info dev_info;
1100 RTE_ETH_FOREACH_DEV(pi) {
1101 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1104 max_rxq_valid = true;
1105 if (dev_info.max_rx_queues < allowed_max_rxq) {
1106 allowed_max_rxq = dev_info.max_rx_queues;
1110 return max_rxq_valid ? allowed_max_rxq : 0;
1114 * Check input rxq is valid or not.
1115 * If input rxq is not greater than any of maximum number
1116 * of RX queues of all ports, it is valid.
1117 * if valid, return 0, else return -1
1120 check_nb_rxq(queueid_t rxq)
1122 queueid_t allowed_max_rxq;
1125 allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
1126 if (rxq > allowed_max_rxq) {
1127 printf("Fail: input rxq (%u) can't be greater "
1128 "than max_rx_queues (%u) of port %u\n",
1138 * Get the allowed maximum number of TX queues.
1139 * *pid return the port id which has minimal value of
1140 * max_tx_queues in all ports.
1143 get_allowed_max_nb_txq(portid_t *pid)
1145 queueid_t allowed_max_txq = RTE_MAX_QUEUES_PER_PORT;
1146 bool max_txq_valid = false;
1148 struct rte_eth_dev_info dev_info;
1150 RTE_ETH_FOREACH_DEV(pi) {
1151 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1154 max_txq_valid = true;
1155 if (dev_info.max_tx_queues < allowed_max_txq) {
1156 allowed_max_txq = dev_info.max_tx_queues;
1160 return max_txq_valid ? allowed_max_txq : 0;
1164 * Check input txq is valid or not.
1165 * If input txq is not greater than any of maximum number
1166 * of TX queues of all ports, it is valid.
1167 * if valid, return 0, else return -1
1170 check_nb_txq(queueid_t txq)
1172 queueid_t allowed_max_txq;
1175 allowed_max_txq = get_allowed_max_nb_txq(&pid);
1176 if (txq > allowed_max_txq) {
1177 printf("Fail: input txq (%u) can't be greater "
1178 "than max_tx_queues (%u) of port %u\n",
1188 * Get the allowed maximum number of RXDs of every rx queue.
1189 * *pid return the port id which has minimal value of
1190 * max_rxd in all queues of all ports.
1193 get_allowed_max_nb_rxd(portid_t *pid)
1195 uint16_t allowed_max_rxd = UINT16_MAX;
1197 struct rte_eth_dev_info dev_info;
1199 RTE_ETH_FOREACH_DEV(pi) {
1200 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1203 if (dev_info.rx_desc_lim.nb_max < allowed_max_rxd) {
1204 allowed_max_rxd = dev_info.rx_desc_lim.nb_max;
1208 return allowed_max_rxd;
1212 * Get the allowed minimal number of RXDs of every rx queue.
1213 * *pid return the port id which has minimal value of
1214 * min_rxd in all queues of all ports.
1217 get_allowed_min_nb_rxd(portid_t *pid)
1219 uint16_t allowed_min_rxd = 0;
1221 struct rte_eth_dev_info dev_info;
1223 RTE_ETH_FOREACH_DEV(pi) {
1224 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1227 if (dev_info.rx_desc_lim.nb_min > allowed_min_rxd) {
1228 allowed_min_rxd = dev_info.rx_desc_lim.nb_min;
1233 return allowed_min_rxd;
1237 * Check input rxd is valid or not.
1238 * If input rxd is not greater than any of maximum number
1239 * of RXDs of every Rx queues and is not less than any of
1240 * minimal number of RXDs of every Rx queues, it is valid.
1241 * if valid, return 0, else return -1
1244 check_nb_rxd(queueid_t rxd)
1246 uint16_t allowed_max_rxd;
1247 uint16_t allowed_min_rxd;
1250 allowed_max_rxd = get_allowed_max_nb_rxd(&pid);
1251 if (rxd > allowed_max_rxd) {
1252 printf("Fail: input rxd (%u) can't be greater "
1253 "than max_rxds (%u) of port %u\n",
1260 allowed_min_rxd = get_allowed_min_nb_rxd(&pid);
1261 if (rxd < allowed_min_rxd) {
1262 printf("Fail: input rxd (%u) can't be less "
1263 "than min_rxds (%u) of port %u\n",
1274 * Get the allowed maximum number of TXDs of every rx queues.
1275 * *pid return the port id which has minimal value of
1276 * max_txd in every tx queue.
1279 get_allowed_max_nb_txd(portid_t *pid)
1281 uint16_t allowed_max_txd = UINT16_MAX;
1283 struct rte_eth_dev_info dev_info;
1285 RTE_ETH_FOREACH_DEV(pi) {
1286 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1289 if (dev_info.tx_desc_lim.nb_max < allowed_max_txd) {
1290 allowed_max_txd = dev_info.tx_desc_lim.nb_max;
1294 return allowed_max_txd;
1298 * Get the allowed maximum number of TXDs of every tx queues.
1299 * *pid return the port id which has minimal value of
1300 * min_txd in every tx queue.
1303 get_allowed_min_nb_txd(portid_t *pid)
1305 uint16_t allowed_min_txd = 0;
1307 struct rte_eth_dev_info dev_info;
1309 RTE_ETH_FOREACH_DEV(pi) {
1310 if (eth_dev_info_get_print_err(pi, &dev_info) != 0)
1313 if (dev_info.tx_desc_lim.nb_min > allowed_min_txd) {
1314 allowed_min_txd = dev_info.tx_desc_lim.nb_min;
1319 return allowed_min_txd;
1323 * Check input txd is valid or not.
1324 * If input txd is not greater than any of maximum number
1325 * of TXDs of every Rx queues, it is valid.
1326 * if valid, return 0, else return -1
1329 check_nb_txd(queueid_t txd)
1331 uint16_t allowed_max_txd;
1332 uint16_t allowed_min_txd;
1335 allowed_max_txd = get_allowed_max_nb_txd(&pid);
1336 if (txd > allowed_max_txd) {
1337 printf("Fail: input txd (%u) can't be greater "
1338 "than max_txds (%u) of port %u\n",
1345 allowed_min_txd = get_allowed_min_nb_txd(&pid);
1346 if (txd < allowed_min_txd) {
1347 printf("Fail: input txd (%u) can't be less "
1348 "than min_txds (%u) of port %u\n",
1359 * Get the allowed maximum number of hairpin queues.
1360 * *pid return the port id which has minimal value of
1361 * max_hairpin_queues in all ports.
1364 get_allowed_max_nb_hairpinq(portid_t *pid)
1366 queueid_t allowed_max_hairpinq = RTE_MAX_QUEUES_PER_PORT;
1368 struct rte_eth_hairpin_cap cap;
1370 RTE_ETH_FOREACH_DEV(pi) {
1371 if (rte_eth_dev_hairpin_capability_get(pi, &cap) != 0) {
1375 if (cap.max_nb_queues < allowed_max_hairpinq) {
1376 allowed_max_hairpinq = cap.max_nb_queues;
1380 return allowed_max_hairpinq;
1384 * Check input hairpin is valid or not.
1385 * If input hairpin is not greater than any of maximum number
1386 * of hairpin queues of all ports, it is valid.
1387 * if valid, return 0, else return -1
1390 check_nb_hairpinq(queueid_t hairpinq)
1392 queueid_t allowed_max_hairpinq;
1395 allowed_max_hairpinq = get_allowed_max_nb_hairpinq(&pid);
1396 if (hairpinq > allowed_max_hairpinq) {
1397 printf("Fail: input hairpin (%u) can't be greater "
1398 "than max_hairpin_queues (%u) of port %u\n",
1399 hairpinq, allowed_max_hairpinq, pid);
1409 struct rte_port *port;
1410 struct rte_mempool *mbp;
1411 unsigned int nb_mbuf_per_pool;
1413 uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
1414 struct rte_gro_param gro_param;
1421 memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
1423 /* Configuration of logical cores. */
1424 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
1425 sizeof(struct fwd_lcore *) * nb_lcores,
1426 RTE_CACHE_LINE_SIZE);
1427 if (fwd_lcores == NULL) {
1428 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
1429 "failed\n", nb_lcores);
1431 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1432 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
1433 sizeof(struct fwd_lcore),
1434 RTE_CACHE_LINE_SIZE);
1435 if (fwd_lcores[lc_id] == NULL) {
1436 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
1439 fwd_lcores[lc_id]->cpuid_idx = lc_id;
1442 RTE_ETH_FOREACH_DEV(pid) {
1444 /* Apply default TxRx configuration for all ports */
1445 port->dev_conf.txmode = tx_mode;
1446 port->dev_conf.rxmode = rx_mode;
1448 ret = eth_dev_info_get_print_err(pid, &port->dev_info);
1450 rte_exit(EXIT_FAILURE,
1451 "rte_eth_dev_info_get() failed\n");
1453 ret = update_jumbo_frame_offload(pid);
1455 printf("Updating jumbo frame offload failed for port %u\n",
1458 if (!(port->dev_info.tx_offload_capa &
1459 DEV_TX_OFFLOAD_MBUF_FAST_FREE))
1460 port->dev_conf.txmode.offloads &=
1461 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
1463 if (port_numa[pid] != NUMA_NO_CONFIG)
1464 port_per_socket[port_numa[pid]]++;
1466 uint32_t socket_id = rte_eth_dev_socket_id(pid);
1469 * if socket_id is invalid,
1470 * set to the first available socket.
1472 if (check_socket_id(socket_id) < 0)
1473 socket_id = socket_ids[0];
1474 port_per_socket[socket_id]++;
1478 /* Apply Rx offloads configuration */
1479 for (k = 0; k < port->dev_info.max_rx_queues; k++)
1480 port->rx_conf[k].offloads =
1481 port->dev_conf.rxmode.offloads;
1482 /* Apply Tx offloads configuration */
1483 for (k = 0; k < port->dev_info.max_tx_queues; k++)
1484 port->tx_conf[k].offloads =
1485 port->dev_conf.txmode.offloads;
1487 /* set flag to initialize port/queue */
1488 port->need_reconfig = 1;
1489 port->need_reconfig_queues = 1;
1490 port->tx_metadata = 0;
1492 /* Check for maximum number of segments per MTU. Accordingly
1493 * update the mbuf data size.
1495 if (port->dev_info.rx_desc_lim.nb_mtu_seg_max != UINT16_MAX &&
1496 port->dev_info.rx_desc_lim.nb_mtu_seg_max != 0) {
1497 data_size = rx_mode.max_rx_pkt_len /
1498 port->dev_info.rx_desc_lim.nb_mtu_seg_max;
1500 if ((data_size + RTE_PKTMBUF_HEADROOM) >
1501 mbuf_data_size[0]) {
1502 mbuf_data_size[0] = data_size +
1503 RTE_PKTMBUF_HEADROOM;
1510 TESTPMD_LOG(WARNING,
1511 "Configured mbuf size of the first segment %hu\n",
1514 * Create pools of mbuf.
1515 * If NUMA support is disabled, create a single pool of mbuf in
1516 * socket 0 memory by default.
1517 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
1519 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
1520 * nb_txd can be configured at run time.
1522 if (param_total_num_mbufs)
1523 nb_mbuf_per_pool = param_total_num_mbufs;
1525 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
1526 (nb_lcores * mb_mempool_cache) +
1527 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
1528 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
1534 for (i = 0; i < num_sockets; i++)
1535 for (j = 0; j < mbuf_data_size_n; j++)
1536 mempools[i * MAX_SEGS_BUFFER_SPLIT + j] =
1537 mbuf_pool_create(mbuf_data_size[j],
1543 for (i = 0; i < mbuf_data_size_n; i++)
1544 mempools[i] = mbuf_pool_create
1547 socket_num == UMA_NO_CONFIG ?
1553 gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
1554 DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
1556 * Records which Mbuf pool to use by each logical core, if needed.
1558 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1559 mbp = mbuf_pool_find(
1560 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]), 0);
1563 mbp = mbuf_pool_find(0, 0);
1564 fwd_lcores[lc_id]->mbp = mbp;
1565 /* initialize GSO context */
1566 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
1567 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
1568 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
1569 fwd_lcores[lc_id]->gso_ctx.gso_size = RTE_ETHER_MAX_LEN -
1571 fwd_lcores[lc_id]->gso_ctx.flag = 0;
1574 /* Configuration of packet forwarding streams. */
1575 if (init_fwd_streams() < 0)
1576 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
1580 /* create a gro context for each lcore */
1581 gro_param.gro_types = RTE_GRO_TCP_IPV4;
1582 gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
1583 gro_param.max_item_per_flow = MAX_PKT_BURST;
1584 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1585 gro_param.socket_id = rte_lcore_to_socket_id(
1586 fwd_lcores_cpuids[lc_id]);
1587 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
1588 if (fwd_lcores[lc_id]->gro_ctx == NULL) {
1589 rte_exit(EXIT_FAILURE,
1590 "rte_gro_ctx_create() failed\n");
1597 reconfig(portid_t new_port_id, unsigned socket_id)
1599 struct rte_port *port;
1602 /* Reconfiguration of Ethernet ports. */
1603 port = &ports[new_port_id];
1605 ret = eth_dev_info_get_print_err(new_port_id, &port->dev_info);
1609 /* set flag to initialize port/queue */
1610 port->need_reconfig = 1;
1611 port->need_reconfig_queues = 1;
1612 port->socket_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) {
1630 printf("Fail: nb_rxq(%d) is greater than "
1631 "max_rx_queues(%d)\n", nb_rxq,
1632 port->dev_info.max_rx_queues);
1635 if (nb_txq > port->dev_info.max_tx_queues) {
1636 printf("Fail: nb_txq(%d) is greater than "
1637 "max_tx_queues(%d)\n", nb_txq,
1638 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);
1665 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
1668 nb_fwd_streams_new = (streamid_t)(nb_ports * q);
1669 if (nb_fwd_streams_new == nb_fwd_streams)
1672 if (fwd_streams != NULL) {
1673 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1674 if (fwd_streams[sm_id] == NULL)
1676 rte_free(fwd_streams[sm_id]);
1677 fwd_streams[sm_id] = NULL;
1679 rte_free(fwd_streams);
1684 nb_fwd_streams = nb_fwd_streams_new;
1685 if (nb_fwd_streams) {
1686 fwd_streams = rte_zmalloc("testpmd: fwd_streams",
1687 sizeof(struct fwd_stream *) * nb_fwd_streams,
1688 RTE_CACHE_LINE_SIZE);
1689 if (fwd_streams == NULL)
1690 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
1691 " (struct fwd_stream *)) failed\n",
1694 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1695 fwd_streams[sm_id] = rte_zmalloc("testpmd:"
1696 " struct fwd_stream", sizeof(struct fwd_stream),
1697 RTE_CACHE_LINE_SIZE);
1698 if (fwd_streams[sm_id] == NULL)
1699 rte_exit(EXIT_FAILURE, "rte_zmalloc"
1700 "(struct fwd_stream) failed\n");
1708 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
1710 uint64_t total_burst, sburst;
1712 uint64_t burst_stats[4];
1713 uint16_t pktnb_stats[4];
1715 int burst_percent[4], sburstp;
1719 * First compute the total number of packet bursts and the
1720 * two highest numbers of bursts of the same number of packets.
1722 memset(&burst_stats, 0x0, sizeof(burst_stats));
1723 memset(&pktnb_stats, 0x0, sizeof(pktnb_stats));
1725 /* Show stats for 0 burst size always */
1726 total_burst = pbs->pkt_burst_spread[0];
1727 burst_stats[0] = pbs->pkt_burst_spread[0];
1730 /* Find the next 2 burst sizes with highest occurrences. */
1731 for (nb_pkt = 1; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
1732 nb_burst = pbs->pkt_burst_spread[nb_pkt];
1737 total_burst += nb_burst;
1739 if (nb_burst > burst_stats[1]) {
1740 burst_stats[2] = burst_stats[1];
1741 pktnb_stats[2] = pktnb_stats[1];
1742 burst_stats[1] = nb_burst;
1743 pktnb_stats[1] = nb_pkt;
1744 } else if (nb_burst > burst_stats[2]) {
1745 burst_stats[2] = nb_burst;
1746 pktnb_stats[2] = nb_pkt;
1749 if (total_burst == 0)
1752 printf(" %s-bursts : %"PRIu64" [", rx_tx, total_burst);
1753 for (i = 0, sburst = 0, sburstp = 0; i < 4; i++) {
1755 printf("%d%% of other]\n", 100 - sburstp);
1759 sburst += burst_stats[i];
1760 if (sburst == total_burst) {
1761 printf("%d%% of %d pkts]\n",
1762 100 - sburstp, (int) pktnb_stats[i]);
1767 (double)burst_stats[i] / total_burst * 100;
1768 printf("%d%% of %d pkts + ",
1769 burst_percent[i], (int) pktnb_stats[i]);
1770 sburstp += burst_percent[i];
1775 fwd_stream_stats_display(streamid_t stream_id)
1777 struct fwd_stream *fs;
1778 static const char *fwd_top_stats_border = "-------";
1780 fs = fwd_streams[stream_id];
1781 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1782 (fs->fwd_dropped == 0))
1784 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1785 "TX Port=%2d/Queue=%2d %s\n",
1786 fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1787 fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1788 printf(" RX-packets: %-14"PRIu64" TX-packets: %-14"PRIu64
1789 " TX-dropped: %-14"PRIu64,
1790 fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1792 /* if checksum mode */
1793 if (cur_fwd_eng == &csum_fwd_engine) {
1794 printf(" RX- bad IP checksum: %-14"PRIu64
1795 " Rx- bad L4 checksum: %-14"PRIu64
1796 " Rx- bad outer L4 checksum: %-14"PRIu64"\n",
1797 fs->rx_bad_ip_csum, fs->rx_bad_l4_csum,
1798 fs->rx_bad_outer_l4_csum);
1803 if (record_burst_stats) {
1804 pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1805 pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1810 fwd_stats_display(void)
1812 static const char *fwd_stats_border = "----------------------";
1813 static const char *acc_stats_border = "+++++++++++++++";
1815 struct fwd_stream *rx_stream;
1816 struct fwd_stream *tx_stream;
1817 uint64_t tx_dropped;
1818 uint64_t rx_bad_ip_csum;
1819 uint64_t rx_bad_l4_csum;
1820 uint64_t rx_bad_outer_l4_csum;
1821 } ports_stats[RTE_MAX_ETHPORTS];
1822 uint64_t total_rx_dropped = 0;
1823 uint64_t total_tx_dropped = 0;
1824 uint64_t total_rx_nombuf = 0;
1825 struct rte_eth_stats stats;
1826 uint64_t fwd_cycles = 0;
1827 uint64_t total_recv = 0;
1828 uint64_t total_xmit = 0;
1829 struct rte_port *port;
1834 memset(ports_stats, 0, sizeof(ports_stats));
1836 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1837 struct fwd_stream *fs = fwd_streams[sm_id];
1839 if (cur_fwd_config.nb_fwd_streams >
1840 cur_fwd_config.nb_fwd_ports) {
1841 fwd_stream_stats_display(sm_id);
1843 ports_stats[fs->tx_port].tx_stream = fs;
1844 ports_stats[fs->rx_port].rx_stream = fs;
1847 ports_stats[fs->tx_port].tx_dropped += fs->fwd_dropped;
1849 ports_stats[fs->rx_port].rx_bad_ip_csum += fs->rx_bad_ip_csum;
1850 ports_stats[fs->rx_port].rx_bad_l4_csum += fs->rx_bad_l4_csum;
1851 ports_stats[fs->rx_port].rx_bad_outer_l4_csum +=
1852 fs->rx_bad_outer_l4_csum;
1854 if (record_core_cycles)
1855 fwd_cycles += fs->core_cycles;
1857 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1858 pt_id = fwd_ports_ids[i];
1859 port = &ports[pt_id];
1861 rte_eth_stats_get(pt_id, &stats);
1862 stats.ipackets -= port->stats.ipackets;
1863 stats.opackets -= port->stats.opackets;
1864 stats.ibytes -= port->stats.ibytes;
1865 stats.obytes -= port->stats.obytes;
1866 stats.imissed -= port->stats.imissed;
1867 stats.oerrors -= port->stats.oerrors;
1868 stats.rx_nombuf -= port->stats.rx_nombuf;
1870 total_recv += stats.ipackets;
1871 total_xmit += stats.opackets;
1872 total_rx_dropped += stats.imissed;
1873 total_tx_dropped += ports_stats[pt_id].tx_dropped;
1874 total_tx_dropped += stats.oerrors;
1875 total_rx_nombuf += stats.rx_nombuf;
1877 printf("\n %s Forward statistics for port %-2d %s\n",
1878 fwd_stats_border, pt_id, fwd_stats_border);
1880 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64
1881 "RX-total: %-"PRIu64"\n", stats.ipackets, stats.imissed,
1882 stats.ipackets + stats.imissed);
1884 if (cur_fwd_eng == &csum_fwd_engine)
1885 printf(" Bad-ipcsum: %-14"PRIu64
1886 " Bad-l4csum: %-14"PRIu64
1887 "Bad-outer-l4csum: %-14"PRIu64"\n",
1888 ports_stats[pt_id].rx_bad_ip_csum,
1889 ports_stats[pt_id].rx_bad_l4_csum,
1890 ports_stats[pt_id].rx_bad_outer_l4_csum);
1891 if (stats.ierrors + stats.rx_nombuf > 0) {
1892 printf(" RX-error: %-"PRIu64"\n", stats.ierrors);
1893 printf(" RX-nombufs: %-14"PRIu64"\n", stats.rx_nombuf);
1896 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64
1897 "TX-total: %-"PRIu64"\n",
1898 stats.opackets, ports_stats[pt_id].tx_dropped,
1899 stats.opackets + ports_stats[pt_id].tx_dropped);
1901 if (record_burst_stats) {
1902 if (ports_stats[pt_id].rx_stream)
1903 pkt_burst_stats_display("RX",
1904 &ports_stats[pt_id].rx_stream->rx_burst_stats);
1905 if (ports_stats[pt_id].tx_stream)
1906 pkt_burst_stats_display("TX",
1907 &ports_stats[pt_id].tx_stream->tx_burst_stats);
1910 printf(" %s--------------------------------%s\n",
1911 fwd_stats_border, fwd_stats_border);
1914 printf("\n %s Accumulated forward statistics for all ports"
1916 acc_stats_border, acc_stats_border);
1917 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1919 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1921 total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1922 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1923 if (total_rx_nombuf > 0)
1924 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1925 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++"
1927 acc_stats_border, acc_stats_border);
1928 if (record_core_cycles) {
1929 #define CYC_PER_MHZ 1E6
1930 if (total_recv > 0 || total_xmit > 0) {
1931 uint64_t total_pkts = 0;
1932 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 ||
1933 strcmp(cur_fwd_eng->fwd_mode_name, "flowgen") == 0)
1934 total_pkts = total_xmit;
1936 total_pkts = total_recv;
1938 printf("\n CPU cycles/packet=%.2F (total cycles="
1939 "%"PRIu64" / total %s packets=%"PRIu64") at %"PRIu64
1941 (double) fwd_cycles / total_pkts,
1942 fwd_cycles, cur_fwd_eng->fwd_mode_name, total_pkts,
1943 (uint64_t)(rte_get_tsc_hz() / CYC_PER_MHZ));
1949 fwd_stats_reset(void)
1955 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1956 pt_id = fwd_ports_ids[i];
1957 rte_eth_stats_get(pt_id, &ports[pt_id].stats);
1959 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1960 struct fwd_stream *fs = fwd_streams[sm_id];
1964 fs->fwd_dropped = 0;
1965 fs->rx_bad_ip_csum = 0;
1966 fs->rx_bad_l4_csum = 0;
1967 fs->rx_bad_outer_l4_csum = 0;
1969 memset(&fs->rx_burst_stats, 0, sizeof(fs->rx_burst_stats));
1970 memset(&fs->tx_burst_stats, 0, sizeof(fs->tx_burst_stats));
1971 fs->core_cycles = 0;
1976 flush_fwd_rx_queues(void)
1978 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1985 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1986 uint64_t timer_period;
1988 /* convert to number of cycles */
1989 timer_period = rte_get_timer_hz(); /* 1 second timeout */
1991 for (j = 0; j < 2; j++) {
1992 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1993 for (rxq = 0; rxq < nb_rxq; rxq++) {
1994 port_id = fwd_ports_ids[rxp];
1996 * testpmd can stuck in the below do while loop
1997 * if rte_eth_rx_burst() always returns nonzero
1998 * packets. So timer is added to exit this loop
1999 * after 1sec timer expiry.
2001 prev_tsc = rte_rdtsc();
2003 nb_rx = rte_eth_rx_burst(port_id, rxq,
2004 pkts_burst, MAX_PKT_BURST);
2005 for (i = 0; i < nb_rx; i++)
2006 rte_pktmbuf_free(pkts_burst[i]);
2008 cur_tsc = rte_rdtsc();
2009 diff_tsc = cur_tsc - prev_tsc;
2010 timer_tsc += diff_tsc;
2011 } while ((nb_rx > 0) &&
2012 (timer_tsc < timer_period));
2016 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
2021 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
2023 struct fwd_stream **fsm;
2026 #ifdef RTE_LIB_BITRATESTATS
2027 uint64_t tics_per_1sec;
2028 uint64_t tics_datum;
2029 uint64_t tics_current;
2030 uint16_t i, cnt_ports;
2032 cnt_ports = nb_ports;
2033 tics_datum = rte_rdtsc();
2034 tics_per_1sec = rte_get_timer_hz();
2036 fsm = &fwd_streams[fc->stream_idx];
2037 nb_fs = fc->stream_nb;
2039 for (sm_id = 0; sm_id < nb_fs; sm_id++)
2040 (*pkt_fwd)(fsm[sm_id]);
2041 #ifdef RTE_LIB_BITRATESTATS
2042 if (bitrate_enabled != 0 &&
2043 bitrate_lcore_id == rte_lcore_id()) {
2044 tics_current = rte_rdtsc();
2045 if (tics_current - tics_datum >= tics_per_1sec) {
2046 /* Periodic bitrate calculation */
2047 for (i = 0; i < cnt_ports; i++)
2048 rte_stats_bitrate_calc(bitrate_data,
2050 tics_datum = tics_current;
2054 #ifdef RTE_LIB_LATENCYSTATS
2055 if (latencystats_enabled != 0 &&
2056 latencystats_lcore_id == rte_lcore_id())
2057 rte_latencystats_update();
2060 } while (! fc->stopped);
2064 start_pkt_forward_on_core(void *fwd_arg)
2066 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
2067 cur_fwd_config.fwd_eng->packet_fwd);
2072 * Run the TXONLY packet forwarding engine to send a single burst of packets.
2073 * Used to start communication flows in network loopback test configurations.
2076 run_one_txonly_burst_on_core(void *fwd_arg)
2078 struct fwd_lcore *fwd_lc;
2079 struct fwd_lcore tmp_lcore;
2081 fwd_lc = (struct fwd_lcore *) fwd_arg;
2082 tmp_lcore = *fwd_lc;
2083 tmp_lcore.stopped = 1;
2084 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
2089 * Launch packet forwarding:
2090 * - Setup per-port forwarding context.
2091 * - launch logical cores with their forwarding configuration.
2094 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
2096 port_fwd_begin_t port_fwd_begin;
2101 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
2102 if (port_fwd_begin != NULL) {
2103 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2104 (*port_fwd_begin)(fwd_ports_ids[i]);
2106 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
2107 lc_id = fwd_lcores_cpuids[i];
2108 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
2109 fwd_lcores[i]->stopped = 0;
2110 diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
2111 fwd_lcores[i], lc_id);
2113 printf("launch lcore %u failed - diag=%d\n",
2120 * Launch packet forwarding configuration.
2123 start_packet_forwarding(int with_tx_first)
2125 port_fwd_begin_t port_fwd_begin;
2126 port_fwd_end_t port_fwd_end;
2127 struct rte_port *port;
2131 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
2132 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
2134 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
2135 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
2137 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
2138 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
2139 (!nb_rxq || !nb_txq))
2140 rte_exit(EXIT_FAILURE,
2141 "Either rxq or txq are 0, cannot use %s fwd mode\n",
2142 cur_fwd_eng->fwd_mode_name);
2144 if (all_ports_started() == 0) {
2145 printf("Not all ports were started\n");
2148 if (test_done == 0) {
2149 printf("Packet forwarding already started\n");
2155 for (i = 0; i < nb_fwd_ports; i++) {
2156 pt_id = fwd_ports_ids[i];
2157 port = &ports[pt_id];
2158 if (!port->dcb_flag) {
2159 printf("In DCB mode, all forwarding ports must "
2160 "be configured in this mode.\n");
2164 if (nb_fwd_lcores == 1) {
2165 printf("In DCB mode,the nb forwarding cores "
2166 "should be larger than 1.\n");
2175 flush_fwd_rx_queues();
2177 pkt_fwd_config_display(&cur_fwd_config);
2178 rxtx_config_display();
2181 if (with_tx_first) {
2182 port_fwd_begin = tx_only_engine.port_fwd_begin;
2183 if (port_fwd_begin != NULL) {
2184 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2185 (*port_fwd_begin)(fwd_ports_ids[i]);
2187 while (with_tx_first--) {
2188 launch_packet_forwarding(
2189 run_one_txonly_burst_on_core);
2190 rte_eal_mp_wait_lcore();
2192 port_fwd_end = tx_only_engine.port_fwd_end;
2193 if (port_fwd_end != NULL) {
2194 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2195 (*port_fwd_end)(fwd_ports_ids[i]);
2198 launch_packet_forwarding(start_pkt_forward_on_core);
2202 stop_packet_forwarding(void)
2204 port_fwd_end_t port_fwd_end;
2210 printf("Packet forwarding not started\n");
2213 printf("Telling cores to stop...");
2214 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
2215 fwd_lcores[lc_id]->stopped = 1;
2216 printf("\nWaiting for lcores to finish...\n");
2217 rte_eal_mp_wait_lcore();
2218 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
2219 if (port_fwd_end != NULL) {
2220 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
2221 pt_id = fwd_ports_ids[i];
2222 (*port_fwd_end)(pt_id);
2226 fwd_stats_display();
2228 printf("\nDone.\n");
2233 dev_set_link_up(portid_t pid)
2235 if (rte_eth_dev_set_link_up(pid) < 0)
2236 printf("\nSet link up fail.\n");
2240 dev_set_link_down(portid_t pid)
2242 if (rte_eth_dev_set_link_down(pid) < 0)
2243 printf("\nSet link down fail.\n");
2247 all_ports_started(void)
2250 struct rte_port *port;
2252 RTE_ETH_FOREACH_DEV(pi) {
2254 /* Check if there is a port which is not started */
2255 if ((port->port_status != RTE_PORT_STARTED) &&
2256 (port->slave_flag == 0))
2260 /* No port is not started */
2265 port_is_stopped(portid_t port_id)
2267 struct rte_port *port = &ports[port_id];
2269 if ((port->port_status != RTE_PORT_STOPPED) &&
2270 (port->slave_flag == 0))
2276 all_ports_stopped(void)
2280 RTE_ETH_FOREACH_DEV(pi) {
2281 if (!port_is_stopped(pi))
2289 port_is_started(portid_t port_id)
2291 if (port_id_is_invalid(port_id, ENABLED_WARN))
2294 if (ports[port_id].port_status != RTE_PORT_STARTED)
2300 /* Configure the Rx and Tx hairpin queues for the selected port. */
2302 setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi)
2305 struct rte_eth_hairpin_conf hairpin_conf = {
2310 struct rte_port *port = &ports[pi];
2311 uint16_t peer_rx_port = pi;
2312 uint16_t peer_tx_port = pi;
2313 uint32_t manual = 1;
2314 uint32_t tx_exp = hairpin_mode & 0x10;
2316 if (!(hairpin_mode & 0xf)) {
2320 } else if (hairpin_mode & 0x1) {
2321 peer_tx_port = rte_eth_find_next_owned_by(pi + 1,
2322 RTE_ETH_DEV_NO_OWNER);
2323 if (peer_tx_port >= RTE_MAX_ETHPORTS)
2324 peer_tx_port = rte_eth_find_next_owned_by(0,
2325 RTE_ETH_DEV_NO_OWNER);
2326 if (p_pi != RTE_MAX_ETHPORTS) {
2327 peer_rx_port = p_pi;
2331 /* Last port will be the peer RX port of the first. */
2332 RTE_ETH_FOREACH_DEV(next_pi)
2333 peer_rx_port = next_pi;
2336 } else if (hairpin_mode & 0x2) {
2338 peer_rx_port = p_pi;
2340 peer_rx_port = rte_eth_find_next_owned_by(pi + 1,
2341 RTE_ETH_DEV_NO_OWNER);
2342 if (peer_rx_port >= RTE_MAX_ETHPORTS)
2345 peer_tx_port = peer_rx_port;
2349 for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) {
2350 hairpin_conf.peers[0].port = peer_rx_port;
2351 hairpin_conf.peers[0].queue = i + nb_rxq;
2352 hairpin_conf.manual_bind = !!manual;
2353 hairpin_conf.tx_explicit = !!tx_exp;
2354 diag = rte_eth_tx_hairpin_queue_setup
2355 (pi, qi, nb_txd, &hairpin_conf);
2360 /* Fail to setup rx queue, return */
2361 if (rte_atomic16_cmpset(&(port->port_status),
2363 RTE_PORT_STOPPED) == 0)
2364 printf("Port %d can not be set back "
2365 "to stopped\n", pi);
2366 printf("Fail to configure port %d hairpin "
2368 /* try to reconfigure queues next time */
2369 port->need_reconfig_queues = 1;
2372 for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) {
2373 hairpin_conf.peers[0].port = peer_tx_port;
2374 hairpin_conf.peers[0].queue = i + nb_txq;
2375 hairpin_conf.manual_bind = !!manual;
2376 hairpin_conf.tx_explicit = !!tx_exp;
2377 diag = rte_eth_rx_hairpin_queue_setup
2378 (pi, qi, nb_rxd, &hairpin_conf);
2383 /* Fail to setup rx queue, return */
2384 if (rte_atomic16_cmpset(&(port->port_status),
2386 RTE_PORT_STOPPED) == 0)
2387 printf("Port %d can not be set back "
2388 "to stopped\n", pi);
2389 printf("Fail to configure port %d hairpin "
2391 /* try to reconfigure queues next time */
2392 port->need_reconfig_queues = 1;
2398 /* Configure the Rx with optional split. */
2400 rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
2401 uint16_t nb_rx_desc, unsigned int socket_id,
2402 struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
2404 union rte_eth_rxseg rx_useg[MAX_SEGS_BUFFER_SPLIT] = {};
2405 unsigned int i, mp_n;
2408 if (rx_pkt_nb_segs <= 1 ||
2409 (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) {
2410 rx_conf->rx_seg = NULL;
2411 rx_conf->rx_nseg = 0;
2412 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id,
2413 nb_rx_desc, socket_id,
2417 for (i = 0; i < rx_pkt_nb_segs; i++) {
2418 struct rte_eth_rxseg_split *rx_seg = &rx_useg[i].split;
2419 struct rte_mempool *mpx;
2421 * Use last valid pool for the segments with number
2422 * exceeding the pool index.
2424 mp_n = (i > mbuf_data_size_n) ? mbuf_data_size_n - 1 : i;
2425 mpx = mbuf_pool_find(socket_id, mp_n);
2426 /* Handle zero as mbuf data buffer size. */
2427 rx_seg->length = rx_pkt_seg_lengths[i] ?
2428 rx_pkt_seg_lengths[i] :
2429 mbuf_data_size[mp_n];
2430 rx_seg->offset = i < rx_pkt_nb_offs ?
2431 rx_pkt_seg_offsets[i] : 0;
2432 rx_seg->mp = mpx ? mpx : mp;
2434 rx_conf->rx_nseg = rx_pkt_nb_segs;
2435 rx_conf->rx_seg = rx_useg;
2436 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id, nb_rx_desc,
2437 socket_id, rx_conf, NULL);
2438 rx_conf->rx_seg = NULL;
2439 rx_conf->rx_nseg = 0;
2444 start_port(portid_t pid)
2446 int diag, need_check_link_status = -1;
2448 portid_t p_pi = RTE_MAX_ETHPORTS;
2449 portid_t pl[RTE_MAX_ETHPORTS];
2450 portid_t peer_pl[RTE_MAX_ETHPORTS];
2451 uint16_t cnt_pi = 0;
2452 uint16_t cfg_pi = 0;
2455 struct rte_port *port;
2456 struct rte_ether_addr mac_addr;
2457 struct rte_eth_hairpin_cap cap;
2459 if (port_id_is_invalid(pid, ENABLED_WARN))
2464 RTE_ETH_FOREACH_DEV(pi) {
2465 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2468 need_check_link_status = 0;
2470 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
2471 RTE_PORT_HANDLING) == 0) {
2472 printf("Port %d is now not stopped\n", pi);
2476 if (port->need_reconfig > 0) {
2477 port->need_reconfig = 0;
2479 if (flow_isolate_all) {
2480 int ret = port_flow_isolate(pi, 1);
2482 printf("Failed to apply isolated"
2483 " mode on port %d\n", pi);
2487 configure_rxtx_dump_callbacks(0);
2488 printf("Configuring Port %d (socket %u)\n", pi,
2490 if (nb_hairpinq > 0 &&
2491 rte_eth_dev_hairpin_capability_get(pi, &cap)) {
2492 printf("Port %d doesn't support hairpin "
2496 /* configure port */
2497 diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq,
2498 nb_txq + nb_hairpinq,
2501 if (rte_atomic16_cmpset(&(port->port_status),
2502 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2503 printf("Port %d can not be set back "
2504 "to stopped\n", pi);
2505 printf("Fail to configure port %d\n", pi);
2506 /* try to reconfigure port next time */
2507 port->need_reconfig = 1;
2511 if (port->need_reconfig_queues > 0) {
2512 port->need_reconfig_queues = 0;
2513 /* setup tx queues */
2514 for (qi = 0; qi < nb_txq; qi++) {
2515 if ((numa_support) &&
2516 (txring_numa[pi] != NUMA_NO_CONFIG))
2517 diag = rte_eth_tx_queue_setup(pi, qi,
2518 port->nb_tx_desc[qi],
2520 &(port->tx_conf[qi]));
2522 diag = rte_eth_tx_queue_setup(pi, qi,
2523 port->nb_tx_desc[qi],
2525 &(port->tx_conf[qi]));
2530 /* Fail to setup tx queue, return */
2531 if (rte_atomic16_cmpset(&(port->port_status),
2533 RTE_PORT_STOPPED) == 0)
2534 printf("Port %d can not be set back "
2535 "to stopped\n", pi);
2536 printf("Fail to configure port %d tx queues\n",
2538 /* try to reconfigure queues next time */
2539 port->need_reconfig_queues = 1;
2542 for (qi = 0; qi < nb_rxq; qi++) {
2543 /* setup rx queues */
2544 if ((numa_support) &&
2545 (rxring_numa[pi] != NUMA_NO_CONFIG)) {
2546 struct rte_mempool * mp =
2548 (rxring_numa[pi], 0);
2550 printf("Failed to setup RX queue:"
2551 "No mempool allocation"
2552 " on the socket %d\n",
2557 diag = rx_queue_setup(pi, qi,
2558 port->nb_rx_desc[qi],
2560 &(port->rx_conf[qi]),
2563 struct rte_mempool *mp =
2565 (port->socket_id, 0);
2567 printf("Failed to setup RX queue:"
2568 "No mempool allocation"
2569 " on the socket %d\n",
2573 diag = rx_queue_setup(pi, qi,
2574 port->nb_rx_desc[qi],
2576 &(port->rx_conf[qi]),
2582 /* Fail to setup rx queue, return */
2583 if (rte_atomic16_cmpset(&(port->port_status),
2585 RTE_PORT_STOPPED) == 0)
2586 printf("Port %d can not be set back "
2587 "to stopped\n", pi);
2588 printf("Fail to configure port %d rx queues\n",
2590 /* try to reconfigure queues next time */
2591 port->need_reconfig_queues = 1;
2594 /* setup hairpin queues */
2595 if (setup_hairpin_queues(pi, p_pi, cnt_pi) != 0)
2598 configure_rxtx_dump_callbacks(verbose_level);
2600 diag = rte_eth_dev_set_ptypes(pi, RTE_PTYPE_UNKNOWN,
2604 "Port %d: Failed to disable Ptype parsing\n",
2612 if (rte_eth_dev_start(pi) < 0) {
2613 printf("Fail to start port %d\n", pi);
2615 /* Fail to setup rx queue, return */
2616 if (rte_atomic16_cmpset(&(port->port_status),
2617 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2618 printf("Port %d can not be set back to "
2623 if (rte_atomic16_cmpset(&(port->port_status),
2624 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2625 printf("Port %d can not be set into started\n", pi);
2627 if (eth_macaddr_get_print_err(pi, &mac_addr) == 0)
2628 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2629 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
2630 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
2631 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
2633 /* at least one port started, need checking link status */
2634 need_check_link_status = 1;
2639 if (need_check_link_status == 1 && !no_link_check)
2640 check_all_ports_link_status(RTE_PORT_ALL);
2641 else if (need_check_link_status == 0)
2642 printf("Please stop the ports first\n");
2644 if (hairpin_mode & 0xf) {
2648 /* bind all started hairpin ports */
2649 for (i = 0; i < cfg_pi; i++) {
2651 /* bind current Tx to all peer Rx */
2652 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2653 RTE_MAX_ETHPORTS, 1);
2656 for (j = 0; j < peer_pi; j++) {
2657 if (!port_is_started(peer_pl[j]))
2659 diag = rte_eth_hairpin_bind(pi, peer_pl[j]);
2661 printf("Error during binding hairpin"
2662 " Tx port %u to %u: %s\n",
2664 rte_strerror(-diag));
2668 /* bind all peer Tx to current Rx */
2669 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2670 RTE_MAX_ETHPORTS, 0);
2673 for (j = 0; j < peer_pi; j++) {
2674 if (!port_is_started(peer_pl[j]))
2676 diag = rte_eth_hairpin_bind(peer_pl[j], pi);
2678 printf("Error during binding hairpin"
2679 " Tx port %u to %u: %s\n",
2681 rte_strerror(-diag));
2693 stop_port(portid_t pid)
2696 struct rte_port *port;
2697 int need_check_link_status = 0;
2698 portid_t peer_pl[RTE_MAX_ETHPORTS];
2706 if (port_id_is_invalid(pid, ENABLED_WARN))
2709 printf("Stopping ports...\n");
2711 RTE_ETH_FOREACH_DEV(pi) {
2712 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2715 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2716 printf("Please remove port %d from forwarding configuration.\n", pi);
2720 if (port_is_bonding_slave(pi)) {
2721 printf("Please remove port %d from bonded device.\n", pi);
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 printf("Port %d can not be set into stopped\n", pi);
2756 need_check_link_status = 1;
2758 if (need_check_link_status && !no_link_check)
2759 check_all_ports_link_status(RTE_PORT_ALL);
2765 remove_invalid_ports_in(portid_t *array, portid_t *total)
2768 portid_t new_total = 0;
2770 for (i = 0; i < *total; i++)
2771 if (!port_id_is_invalid(array[i], DISABLED_WARN)) {
2772 array[new_total] = array[i];
2779 remove_invalid_ports(void)
2781 remove_invalid_ports_in(ports_ids, &nb_ports);
2782 remove_invalid_ports_in(fwd_ports_ids, &nb_fwd_ports);
2783 nb_cfg_ports = nb_fwd_ports;
2787 close_port(portid_t pid)
2790 struct rte_port *port;
2792 if (port_id_is_invalid(pid, ENABLED_WARN))
2795 printf("Closing ports...\n");
2797 RTE_ETH_FOREACH_DEV(pi) {
2798 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2801 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2802 printf("Please remove port %d from forwarding configuration.\n", pi);
2806 if (port_is_bonding_slave(pi)) {
2807 printf("Please remove port %d from bonded device.\n", pi);
2812 if (rte_atomic16_cmpset(&(port->port_status),
2813 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2814 printf("Port %d is already closed\n", pi);
2818 port_flow_flush(pi);
2819 rte_eth_dev_close(pi);
2822 remove_invalid_ports();
2827 reset_port(portid_t pid)
2831 struct rte_port *port;
2833 if (port_id_is_invalid(pid, ENABLED_WARN))
2836 if ((pid == (portid_t)RTE_PORT_ALL && !all_ports_stopped()) ||
2837 (pid != (portid_t)RTE_PORT_ALL && !port_is_stopped(pid))) {
2838 printf("Can not reset port(s), please stop port(s) first.\n");
2842 printf("Resetting ports...\n");
2844 RTE_ETH_FOREACH_DEV(pi) {
2845 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2848 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2849 printf("Please remove port %d from forwarding "
2850 "configuration.\n", pi);
2854 if (port_is_bonding_slave(pi)) {
2855 printf("Please remove port %d from bonded device.\n",
2860 diag = rte_eth_dev_reset(pi);
2863 port->need_reconfig = 1;
2864 port->need_reconfig_queues = 1;
2866 printf("Failed to reset port %d. diag=%d\n", pi, diag);
2874 attach_port(char *identifier)
2877 struct rte_dev_iterator iterator;
2879 printf("Attaching a new port...\n");
2881 if (identifier == NULL) {
2882 printf("Invalid parameters are specified\n");
2886 if (rte_dev_probe(identifier) < 0) {
2887 TESTPMD_LOG(ERR, "Failed to attach port %s\n", identifier);
2891 /* first attach mode: event */
2892 if (setup_on_probe_event) {
2893 /* new ports are detected on RTE_ETH_EVENT_NEW event */
2894 for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++)
2895 if (ports[pi].port_status == RTE_PORT_HANDLING &&
2896 ports[pi].need_setup != 0)
2897 setup_attached_port(pi);
2901 /* second attach mode: iterator */
2902 RTE_ETH_FOREACH_MATCHING_DEV(pi, identifier, &iterator) {
2903 /* setup ports matching the devargs used for probing */
2904 if (port_is_forwarding(pi))
2905 continue; /* port was already attached before */
2906 setup_attached_port(pi);
2911 setup_attached_port(portid_t pi)
2913 unsigned int socket_id;
2916 socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2917 /* if socket_id is invalid, set to the first available socket. */
2918 if (check_socket_id(socket_id) < 0)
2919 socket_id = socket_ids[0];
2920 reconfig(pi, socket_id);
2921 ret = rte_eth_promiscuous_enable(pi);
2923 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n",
2924 pi, rte_strerror(-ret));
2926 ports_ids[nb_ports++] = pi;
2927 fwd_ports_ids[nb_fwd_ports++] = pi;
2928 nb_cfg_ports = nb_fwd_ports;
2929 ports[pi].need_setup = 0;
2930 ports[pi].port_status = RTE_PORT_STOPPED;
2932 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2937 detach_device(struct rte_device *dev)
2942 printf("Device already removed\n");
2946 printf("Removing a device...\n");
2948 RTE_ETH_FOREACH_DEV_OF(sibling, dev) {
2949 if (ports[sibling].port_status != RTE_PORT_CLOSED) {
2950 if (ports[sibling].port_status != RTE_PORT_STOPPED) {
2951 printf("Port %u not stopped\n", sibling);
2954 port_flow_flush(sibling);
2958 if (rte_dev_remove(dev) < 0) {
2959 TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name);
2962 remove_invalid_ports();
2964 printf("Device is detached\n");
2965 printf("Now total ports is %d\n", nb_ports);
2971 detach_port_device(portid_t port_id)
2973 if (port_id_is_invalid(port_id, ENABLED_WARN))
2976 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
2977 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
2978 printf("Port not stopped\n");
2981 printf("Port was not closed\n");
2984 detach_device(rte_eth_devices[port_id].device);
2988 detach_devargs(char *identifier)
2990 struct rte_dev_iterator iterator;
2991 struct rte_devargs da;
2994 printf("Removing a device...\n");
2996 memset(&da, 0, sizeof(da));
2997 if (rte_devargs_parsef(&da, "%s", identifier)) {
2998 printf("cannot parse identifier\n");
3004 RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) {
3005 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
3006 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
3007 printf("Port %u not stopped\n", port_id);
3008 rte_eth_iterator_cleanup(&iterator);
3011 port_flow_flush(port_id);
3015 if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) {
3016 TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n",
3017 da.name, da.bus->name);
3021 remove_invalid_ports();
3023 printf("Device %s is detached\n", identifier);
3024 printf("Now total ports is %d\n", nb_ports);
3036 stop_packet_forwarding();
3038 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3040 if (mp_alloc_type == MP_ALLOC_ANON)
3041 rte_mempool_mem_iter(mempools[i], dma_unmap_cb,
3045 if (ports != NULL) {
3047 RTE_ETH_FOREACH_DEV(pt_id) {
3048 printf("\nStopping port %d...\n", pt_id);
3052 RTE_ETH_FOREACH_DEV(pt_id) {
3053 printf("\nShutting down port %d...\n", pt_id);
3060 ret = rte_dev_event_monitor_stop();
3063 "fail to stop device event monitor.");
3067 ret = rte_dev_event_callback_unregister(NULL,
3068 dev_event_callback, NULL);
3071 "fail to unregister device event callback.\n");
3075 ret = rte_dev_hotplug_handle_disable();
3078 "fail to disable hotplug handling.\n");
3082 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3084 rte_mempool_free(mempools[i]);
3087 printf("\nBye...\n");
3090 typedef void (*cmd_func_t)(void);
3091 struct pmd_test_command {
3092 const char *cmd_name;
3093 cmd_func_t cmd_func;
3096 /* Check the link status of all ports in up to 9s, and print them finally */
3098 check_all_ports_link_status(uint32_t port_mask)
3100 #define CHECK_INTERVAL 100 /* 100ms */
3101 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
3103 uint8_t count, all_ports_up, print_flag = 0;
3104 struct rte_eth_link link;
3106 char link_status[RTE_ETH_LINK_MAX_STR_LEN];
3108 printf("Checking link statuses...\n");
3110 for (count = 0; count <= MAX_CHECK_TIME; count++) {
3112 RTE_ETH_FOREACH_DEV(portid) {
3113 if ((port_mask & (1 << portid)) == 0)
3115 memset(&link, 0, sizeof(link));
3116 ret = rte_eth_link_get_nowait(portid, &link);
3119 if (print_flag == 1)
3120 printf("Port %u link get failed: %s\n",
3121 portid, rte_strerror(-ret));
3124 /* print link status if flag set */
3125 if (print_flag == 1) {
3126 rte_eth_link_to_str(link_status,
3127 sizeof(link_status), &link);
3128 printf("Port %d %s\n", portid, link_status);
3131 /* clear all_ports_up flag if any link down */
3132 if (link.link_status == ETH_LINK_DOWN) {
3137 /* after finally printing all link status, get out */
3138 if (print_flag == 1)
3141 if (all_ports_up == 0) {
3143 rte_delay_ms(CHECK_INTERVAL);
3146 /* set the print_flag if all ports up or timeout */
3147 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
3157 rmv_port_callback(void *arg)
3159 int need_to_start = 0;
3160 int org_no_link_check = no_link_check;
3161 portid_t port_id = (intptr_t)arg;
3162 struct rte_device *dev;
3164 RTE_ETH_VALID_PORTID_OR_RET(port_id);
3166 if (!test_done && port_is_forwarding(port_id)) {
3168 stop_packet_forwarding();
3172 no_link_check = org_no_link_check;
3174 /* Save rte_device pointer before closing ethdev port */
3175 dev = rte_eth_devices[port_id].device;
3176 close_port(port_id);
3177 detach_device(dev); /* might be already removed or have more ports */
3180 start_packet_forwarding(0);
3183 /* This function is used by the interrupt thread */
3185 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
3188 RTE_SET_USED(param);
3189 RTE_SET_USED(ret_param);
3191 if (type >= RTE_ETH_EVENT_MAX) {
3192 fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
3193 port_id, __func__, type);
3195 } else if (event_print_mask & (UINT32_C(1) << type)) {
3196 printf("\nPort %" PRIu16 ": %s event\n", port_id,
3197 eth_event_desc[type]);
3202 case RTE_ETH_EVENT_NEW:
3203 ports[port_id].need_setup = 1;
3204 ports[port_id].port_status = RTE_PORT_HANDLING;
3206 case RTE_ETH_EVENT_INTR_RMV:
3207 if (port_id_is_invalid(port_id, DISABLED_WARN))
3209 if (rte_eal_alarm_set(100000,
3210 rmv_port_callback, (void *)(intptr_t)port_id))
3211 fprintf(stderr, "Could not set up deferred device removal\n");
3213 case RTE_ETH_EVENT_DESTROY:
3214 ports[port_id].port_status = RTE_PORT_CLOSED;
3215 printf("Port %u is closed\n", port_id);
3224 register_eth_event_callback(void)
3227 enum rte_eth_event_type event;
3229 for (event = RTE_ETH_EVENT_UNKNOWN;
3230 event < RTE_ETH_EVENT_MAX; event++) {
3231 ret = rte_eth_dev_callback_register(RTE_ETH_ALL,
3236 TESTPMD_LOG(ERR, "Failed to register callback for "
3237 "%s event\n", eth_event_desc[event]);
3245 /* This function is used by the interrupt thread */
3247 dev_event_callback(const char *device_name, enum rte_dev_event_type type,
3248 __rte_unused void *arg)
3253 if (type >= RTE_DEV_EVENT_MAX) {
3254 fprintf(stderr, "%s called upon invalid event %d\n",
3260 case RTE_DEV_EVENT_REMOVE:
3261 RTE_LOG(DEBUG, EAL, "The device: %s has been removed!\n",
3263 ret = rte_eth_dev_get_port_by_name(device_name, &port_id);
3265 RTE_LOG(ERR, EAL, "can not get port by device %s!\n",
3270 * Because the user's callback is invoked in eal interrupt
3271 * callback, the interrupt callback need to be finished before
3272 * it can be unregistered when detaching device. So finish
3273 * callback soon and use a deferred removal to detach device
3274 * is need. It is a workaround, once the device detaching be
3275 * moved into the eal in the future, the deferred removal could
3278 if (rte_eal_alarm_set(100000,
3279 rmv_port_callback, (void *)(intptr_t)port_id))
3281 "Could not set up deferred device removal\n");
3283 case RTE_DEV_EVENT_ADD:
3284 RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
3286 /* TODO: After finish kernel driver binding,
3287 * begin to attach port.
3296 rxtx_port_config(struct rte_port *port)
3301 for (qid = 0; qid < nb_rxq; qid++) {
3302 offloads = port->rx_conf[qid].offloads;
3303 port->rx_conf[qid] = port->dev_info.default_rxconf;
3305 port->rx_conf[qid].offloads = offloads;
3307 /* Check if any Rx parameters have been passed */
3308 if (rx_pthresh != RTE_PMD_PARAM_UNSET)
3309 port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
3311 if (rx_hthresh != RTE_PMD_PARAM_UNSET)
3312 port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
3314 if (rx_wthresh != RTE_PMD_PARAM_UNSET)
3315 port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
3317 if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
3318 port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
3320 if (rx_drop_en != RTE_PMD_PARAM_UNSET)
3321 port->rx_conf[qid].rx_drop_en = rx_drop_en;
3323 port->nb_rx_desc[qid] = nb_rxd;
3326 for (qid = 0; qid < nb_txq; qid++) {
3327 offloads = port->tx_conf[qid].offloads;
3328 port->tx_conf[qid] = port->dev_info.default_txconf;
3330 port->tx_conf[qid].offloads = offloads;
3332 /* Check if any Tx parameters have been passed */
3333 if (tx_pthresh != RTE_PMD_PARAM_UNSET)
3334 port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
3336 if (tx_hthresh != RTE_PMD_PARAM_UNSET)
3337 port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
3339 if (tx_wthresh != RTE_PMD_PARAM_UNSET)
3340 port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
3342 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
3343 port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
3345 if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
3346 port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
3348 port->nb_tx_desc[qid] = nb_txd;
3353 * Helper function to arrange max_rx_pktlen value and JUMBO_FRAME offload,
3354 * MTU is also aligned if JUMBO_FRAME offload is not set.
3356 * port->dev_info should be set before calling this function.
3358 * return 0 on success, negative on error
3361 update_jumbo_frame_offload(portid_t portid)
3363 struct rte_port *port = &ports[portid];
3364 uint32_t eth_overhead;
3365 uint64_t rx_offloads;
3369 /* Update the max_rx_pkt_len to have MTU as RTE_ETHER_MTU */
3370 if (port->dev_info.max_mtu != UINT16_MAX &&
3371 port->dev_info.max_rx_pktlen > port->dev_info.max_mtu)
3372 eth_overhead = port->dev_info.max_rx_pktlen -
3373 port->dev_info.max_mtu;
3375 eth_overhead = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
3377 rx_offloads = port->dev_conf.rxmode.offloads;
3379 /* Default config value is 0 to use PMD specific overhead */
3380 if (port->dev_conf.rxmode.max_rx_pkt_len == 0)
3381 port->dev_conf.rxmode.max_rx_pkt_len = RTE_ETHER_MTU + eth_overhead;
3383 if (port->dev_conf.rxmode.max_rx_pkt_len <= RTE_ETHER_MTU + eth_overhead) {
3384 rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3387 if ((port->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3388 printf("Frame size (%u) is not supported by port %u\n",
3389 port->dev_conf.rxmode.max_rx_pkt_len,
3393 rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3397 if (rx_offloads != port->dev_conf.rxmode.offloads) {
3400 port->dev_conf.rxmode.offloads = rx_offloads;
3402 /* Apply JUMBO_FRAME offload configuration to Rx queue(s) */
3403 for (qid = 0; qid < port->dev_info.nb_rx_queues; qid++) {
3405 port->rx_conf[qid].offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3407 port->rx_conf[qid].offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3411 /* If JUMBO_FRAME is set MTU conversion done by ethdev layer,
3412 * if unset do it here
3414 if ((rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3415 ret = rte_eth_dev_set_mtu(portid,
3416 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead);
3418 printf("Failed to set MTU to %u for port %u\n",
3419 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead,
3427 init_port_config(void)
3430 struct rte_port *port;
3433 RTE_ETH_FOREACH_DEV(pid) {
3435 port->dev_conf.fdir_conf = fdir_conf;
3437 ret = eth_dev_info_get_print_err(pid, &port->dev_info);
3442 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3443 port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
3444 rss_hf & port->dev_info.flow_type_rss_offloads;
3446 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3447 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
3450 if (port->dcb_flag == 0) {
3451 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
3452 port->dev_conf.rxmode.mq_mode =
3453 (enum rte_eth_rx_mq_mode)
3454 (rx_mq_mode & ETH_MQ_RX_RSS);
3456 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
3459 rxtx_port_config(port);
3461 ret = eth_macaddr_get_print_err(pid, &port->eth_addr);
3465 #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS
3466 rte_pmd_ixgbe_bypass_init(pid);
3469 if (lsc_interrupt &&
3470 (rte_eth_devices[pid].data->dev_flags &
3471 RTE_ETH_DEV_INTR_LSC))
3472 port->dev_conf.intr_conf.lsc = 1;
3473 if (rmv_interrupt &&
3474 (rte_eth_devices[pid].data->dev_flags &
3475 RTE_ETH_DEV_INTR_RMV))
3476 port->dev_conf.intr_conf.rmv = 1;
3480 void set_port_slave_flag(portid_t slave_pid)
3482 struct rte_port *port;
3484 port = &ports[slave_pid];
3485 port->slave_flag = 1;
3488 void clear_port_slave_flag(portid_t slave_pid)
3490 struct rte_port *port;
3492 port = &ports[slave_pid];
3493 port->slave_flag = 0;
3496 uint8_t port_is_bonding_slave(portid_t slave_pid)
3498 struct rte_port *port;
3500 port = &ports[slave_pid];
3501 if ((rte_eth_devices[slave_pid].data->dev_flags &
3502 RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
3507 const uint16_t vlan_tags[] = {
3508 0, 1, 2, 3, 4, 5, 6, 7,
3509 8, 9, 10, 11, 12, 13, 14, 15,
3510 16, 17, 18, 19, 20, 21, 22, 23,
3511 24, 25, 26, 27, 28, 29, 30, 31
3515 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
3516 enum dcb_mode_enable dcb_mode,
3517 enum rte_eth_nb_tcs num_tcs,
3522 struct rte_eth_rss_conf rss_conf;
3525 * Builds up the correct configuration for dcb+vt based on the vlan tags array
3526 * given above, and the number of traffic classes available for use.
3528 if (dcb_mode == DCB_VT_ENABLED) {
3529 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
3530 ð_conf->rx_adv_conf.vmdq_dcb_conf;
3531 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
3532 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf;
3534 /* VMDQ+DCB RX and TX configurations */
3535 vmdq_rx_conf->enable_default_pool = 0;
3536 vmdq_rx_conf->default_pool = 0;
3537 vmdq_rx_conf->nb_queue_pools =
3538 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3539 vmdq_tx_conf->nb_queue_pools =
3540 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3542 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
3543 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
3544 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
3545 vmdq_rx_conf->pool_map[i].pools =
3546 1 << (i % vmdq_rx_conf->nb_queue_pools);
3548 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3549 vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
3550 vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
3553 /* set DCB mode of RX and TX of multiple queues */
3554 eth_conf->rxmode.mq_mode =
3555 (enum rte_eth_rx_mq_mode)
3556 (rx_mq_mode & ETH_MQ_RX_VMDQ_DCB);
3557 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
3559 struct rte_eth_dcb_rx_conf *rx_conf =
3560 ð_conf->rx_adv_conf.dcb_rx_conf;
3561 struct rte_eth_dcb_tx_conf *tx_conf =
3562 ð_conf->tx_adv_conf.dcb_tx_conf;
3564 memset(&rss_conf, 0, sizeof(struct rte_eth_rss_conf));
3566 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
3570 rx_conf->nb_tcs = num_tcs;
3571 tx_conf->nb_tcs = num_tcs;
3573 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3574 rx_conf->dcb_tc[i] = i % num_tcs;
3575 tx_conf->dcb_tc[i] = i % num_tcs;
3578 eth_conf->rxmode.mq_mode =
3579 (enum rte_eth_rx_mq_mode)
3580 (rx_mq_mode & ETH_MQ_RX_DCB_RSS);
3581 eth_conf->rx_adv_conf.rss_conf = rss_conf;
3582 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
3586 eth_conf->dcb_capability_en =
3587 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
3589 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
3595 init_port_dcb_config(portid_t pid,
3596 enum dcb_mode_enable dcb_mode,
3597 enum rte_eth_nb_tcs num_tcs,
3600 struct rte_eth_conf port_conf;
3601 struct rte_port *rte_port;
3605 rte_port = &ports[pid];
3607 memset(&port_conf, 0, sizeof(struct rte_eth_conf));
3608 /* Enter DCB configuration status */
3611 port_conf.rxmode = rte_port->dev_conf.rxmode;
3612 port_conf.txmode = rte_port->dev_conf.txmode;
3614 /*set configuration of DCB in vt mode and DCB in non-vt mode*/
3615 retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
3618 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3620 /* re-configure the device . */
3621 retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
3625 retval = eth_dev_info_get_print_err(pid, &rte_port->dev_info);
3629 /* If dev_info.vmdq_pool_base is greater than 0,
3630 * the queue id of vmdq pools is started after pf queues.
3632 if (dcb_mode == DCB_VT_ENABLED &&
3633 rte_port->dev_info.vmdq_pool_base > 0) {
3634 printf("VMDQ_DCB multi-queue mode is nonsensical"
3635 " for port %d.", pid);
3639 /* Assume the ports in testpmd have the same dcb capability
3640 * and has the same number of rxq and txq in dcb mode
3642 if (dcb_mode == DCB_VT_ENABLED) {
3643 if (rte_port->dev_info.max_vfs > 0) {
3644 nb_rxq = rte_port->dev_info.nb_rx_queues;
3645 nb_txq = rte_port->dev_info.nb_tx_queues;
3647 nb_rxq = rte_port->dev_info.max_rx_queues;
3648 nb_txq = rte_port->dev_info.max_tx_queues;
3651 /*if vt is disabled, use all pf queues */
3652 if (rte_port->dev_info.vmdq_pool_base == 0) {
3653 nb_rxq = rte_port->dev_info.max_rx_queues;
3654 nb_txq = rte_port->dev_info.max_tx_queues;
3656 nb_rxq = (queueid_t)num_tcs;
3657 nb_txq = (queueid_t)num_tcs;
3661 rx_free_thresh = 64;
3663 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
3665 rxtx_port_config(rte_port);
3667 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3668 for (i = 0; i < RTE_DIM(vlan_tags); i++)
3669 rx_vft_set(pid, vlan_tags[i], 1);
3671 retval = eth_macaddr_get_print_err(pid, &rte_port->eth_addr);
3675 rte_port->dcb_flag = 1;
3685 /* Configuration of Ethernet ports. */
3686 ports = rte_zmalloc("testpmd: ports",
3687 sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
3688 RTE_CACHE_LINE_SIZE);
3689 if (ports == NULL) {
3690 rte_exit(EXIT_FAILURE,
3691 "rte_zmalloc(%d struct rte_port) failed\n",
3694 for (i = 0; i < RTE_MAX_ETHPORTS; i++)
3695 LIST_INIT(&ports[i].flow_tunnel_list);
3696 /* Initialize ports NUMA structures */
3697 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3698 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3699 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3713 const char clr[] = { 27, '[', '2', 'J', '\0' };
3714 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
3716 /* Clear screen and move to top left */
3717 printf("%s%s", clr, top_left);
3719 printf("\nPort statistics ====================================");
3720 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
3721 nic_stats_display(fwd_ports_ids[i]);
3727 signal_handler(int signum)
3729 if (signum == SIGINT || signum == SIGTERM) {
3730 printf("\nSignal %d received, preparing to exit...\n",
3732 #ifdef RTE_LIB_PDUMP
3733 /* uninitialize packet capture framework */
3736 #ifdef RTE_LIB_LATENCYSTATS
3737 if (latencystats_enabled != 0)
3738 rte_latencystats_uninit();
3741 /* Set flag to indicate the force termination. */
3743 /* exit with the expected status */
3744 signal(signum, SIG_DFL);
3745 kill(getpid(), signum);
3750 main(int argc, char** argv)
3757 signal(SIGINT, signal_handler);
3758 signal(SIGTERM, signal_handler);
3760 testpmd_logtype = rte_log_register("testpmd");
3761 if (testpmd_logtype < 0)
3762 rte_exit(EXIT_FAILURE, "Cannot register log type");
3763 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3765 diag = rte_eal_init(argc, argv);
3767 rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n",
3768 rte_strerror(rte_errno));
3770 if (rte_eal_process_type() == RTE_PROC_SECONDARY)
3771 rte_exit(EXIT_FAILURE,
3772 "Secondary process type not supported.\n");
3774 ret = register_eth_event_callback();
3776 rte_exit(EXIT_FAILURE, "Cannot register for ethdev events");
3778 #ifdef RTE_LIB_PDUMP
3779 /* initialize packet capture framework */
3784 RTE_ETH_FOREACH_DEV(port_id) {
3785 ports_ids[count] = port_id;
3788 nb_ports = (portid_t) count;
3790 TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3792 /* allocate port structures, and init them */
3795 set_def_fwd_config();
3797 rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n"
3798 "Check the core mask argument\n");
3800 /* Bitrate/latency stats disabled by default */
3801 #ifdef RTE_LIB_BITRATESTATS
3802 bitrate_enabled = 0;
3804 #ifdef RTE_LIB_LATENCYSTATS
3805 latencystats_enabled = 0;
3808 /* on FreeBSD, mlockall() is disabled by default */
3809 #ifdef RTE_EXEC_ENV_FREEBSD
3818 launch_args_parse(argc, argv);
3820 if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3821 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3825 if (tx_first && interactive)
3826 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3827 "interactive mode.\n");
3829 if (tx_first && lsc_interrupt) {
3830 printf("Warning: lsc_interrupt needs to be off when "
3831 " using tx_first. Disabling.\n");
3835 if (!nb_rxq && !nb_txq)
3836 printf("Warning: Either rx or tx queues should be non-zero\n");
3838 if (nb_rxq > 1 && nb_rxq > nb_txq)
3839 printf("Warning: nb_rxq=%d enables RSS configuration, "
3840 "but nb_txq=%d will prevent to fully test it.\n",
3846 ret = rte_dev_hotplug_handle_enable();
3849 "fail to enable hotplug handling.");
3853 ret = rte_dev_event_monitor_start();
3856 "fail to start device event monitoring.");
3860 ret = rte_dev_event_callback_register(NULL,
3861 dev_event_callback, NULL);
3864 "fail to register device event callback\n");
3869 if (!no_device_start && start_port(RTE_PORT_ALL) != 0)
3870 rte_exit(EXIT_FAILURE, "Start ports failed\n");
3872 /* set all ports to promiscuous mode by default */
3873 RTE_ETH_FOREACH_DEV(port_id) {
3874 ret = rte_eth_promiscuous_enable(port_id);
3876 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n",
3877 port_id, rte_strerror(-ret));
3880 /* Init metrics library */
3881 rte_metrics_init(rte_socket_id());
3883 #ifdef RTE_LIB_LATENCYSTATS
3884 if (latencystats_enabled != 0) {
3885 int ret = rte_latencystats_init(1, NULL);
3887 printf("Warning: latencystats init()"
3888 " returned error %d\n", ret);
3889 printf("Latencystats running on lcore %d\n",
3890 latencystats_lcore_id);
3894 /* Setup bitrate stats */
3895 #ifdef RTE_LIB_BITRATESTATS
3896 if (bitrate_enabled != 0) {
3897 bitrate_data = rte_stats_bitrate_create();
3898 if (bitrate_data == NULL)
3899 rte_exit(EXIT_FAILURE,
3900 "Could not allocate bitrate data.\n");
3901 rte_stats_bitrate_reg(bitrate_data);
3905 #ifdef RTE_LIB_CMDLINE
3906 if (strlen(cmdline_filename) != 0)
3907 cmdline_read_from_file(cmdline_filename);
3909 if (interactive == 1) {
3911 printf("Start automatic packet forwarding\n");
3912 start_packet_forwarding(0);
3924 printf("No commandline core given, start packet forwarding\n");
3925 start_packet_forwarding(tx_first);
3926 if (stats_period != 0) {
3927 uint64_t prev_time = 0, cur_time, diff_time = 0;
3928 uint64_t timer_period;
3930 /* Convert to number of cycles */
3931 timer_period = stats_period * rte_get_timer_hz();
3933 while (f_quit == 0) {
3934 cur_time = rte_get_timer_cycles();
3935 diff_time += cur_time - prev_time;
3937 if (diff_time >= timer_period) {
3939 /* Reset the timer */
3942 /* Sleep to avoid unnecessary checks */
3943 prev_time = cur_time;
3948 printf("Press enter to exit\n");
3949 rc = read(0, &c, 1);
3955 ret = rte_eal_cleanup();
3957 rte_exit(EXIT_FAILURE,
3958 "EAL cleanup failed: %s\n", strerror(-ret));
3960 return EXIT_SUCCESS;