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);
1799 printf(" RX- bad outer IP checksum: %-14"PRIu64"\n",
1800 fs->rx_bad_outer_ip_csum);
1805 if (record_burst_stats) {
1806 pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1807 pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1812 fwd_stats_display(void)
1814 static const char *fwd_stats_border = "----------------------";
1815 static const char *acc_stats_border = "+++++++++++++++";
1817 struct fwd_stream *rx_stream;
1818 struct fwd_stream *tx_stream;
1819 uint64_t tx_dropped;
1820 uint64_t rx_bad_ip_csum;
1821 uint64_t rx_bad_l4_csum;
1822 uint64_t rx_bad_outer_l4_csum;
1823 uint64_t rx_bad_outer_ip_csum;
1824 } ports_stats[RTE_MAX_ETHPORTS];
1825 uint64_t total_rx_dropped = 0;
1826 uint64_t total_tx_dropped = 0;
1827 uint64_t total_rx_nombuf = 0;
1828 struct rte_eth_stats stats;
1829 uint64_t fwd_cycles = 0;
1830 uint64_t total_recv = 0;
1831 uint64_t total_xmit = 0;
1832 struct rte_port *port;
1837 memset(ports_stats, 0, sizeof(ports_stats));
1839 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1840 struct fwd_stream *fs = fwd_streams[sm_id];
1842 if (cur_fwd_config.nb_fwd_streams >
1843 cur_fwd_config.nb_fwd_ports) {
1844 fwd_stream_stats_display(sm_id);
1846 ports_stats[fs->tx_port].tx_stream = fs;
1847 ports_stats[fs->rx_port].rx_stream = fs;
1850 ports_stats[fs->tx_port].tx_dropped += fs->fwd_dropped;
1852 ports_stats[fs->rx_port].rx_bad_ip_csum += fs->rx_bad_ip_csum;
1853 ports_stats[fs->rx_port].rx_bad_l4_csum += fs->rx_bad_l4_csum;
1854 ports_stats[fs->rx_port].rx_bad_outer_l4_csum +=
1855 fs->rx_bad_outer_l4_csum;
1856 ports_stats[fs->rx_port].rx_bad_outer_ip_csum +=
1857 fs->rx_bad_outer_ip_csum;
1859 if (record_core_cycles)
1860 fwd_cycles += fs->core_cycles;
1862 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1863 pt_id = fwd_ports_ids[i];
1864 port = &ports[pt_id];
1866 rte_eth_stats_get(pt_id, &stats);
1867 stats.ipackets -= port->stats.ipackets;
1868 stats.opackets -= port->stats.opackets;
1869 stats.ibytes -= port->stats.ibytes;
1870 stats.obytes -= port->stats.obytes;
1871 stats.imissed -= port->stats.imissed;
1872 stats.oerrors -= port->stats.oerrors;
1873 stats.rx_nombuf -= port->stats.rx_nombuf;
1875 total_recv += stats.ipackets;
1876 total_xmit += stats.opackets;
1877 total_rx_dropped += stats.imissed;
1878 total_tx_dropped += ports_stats[pt_id].tx_dropped;
1879 total_tx_dropped += stats.oerrors;
1880 total_rx_nombuf += stats.rx_nombuf;
1882 printf("\n %s Forward statistics for port %-2d %s\n",
1883 fwd_stats_border, pt_id, fwd_stats_border);
1885 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64
1886 "RX-total: %-"PRIu64"\n", stats.ipackets, stats.imissed,
1887 stats.ipackets + stats.imissed);
1889 if (cur_fwd_eng == &csum_fwd_engine) {
1890 printf(" Bad-ipcsum: %-14"PRIu64
1891 " Bad-l4csum: %-14"PRIu64
1892 "Bad-outer-l4csum: %-14"PRIu64"\n",
1893 ports_stats[pt_id].rx_bad_ip_csum,
1894 ports_stats[pt_id].rx_bad_l4_csum,
1895 ports_stats[pt_id].rx_bad_outer_l4_csum);
1896 printf(" Bad-outer-ipcsum: %-14"PRIu64"\n",
1897 ports_stats[pt_id].rx_bad_outer_ip_csum);
1899 if (stats.ierrors + stats.rx_nombuf > 0) {
1900 printf(" RX-error: %-"PRIu64"\n", stats.ierrors);
1901 printf(" RX-nombufs: %-14"PRIu64"\n", stats.rx_nombuf);
1904 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64
1905 "TX-total: %-"PRIu64"\n",
1906 stats.opackets, ports_stats[pt_id].tx_dropped,
1907 stats.opackets + ports_stats[pt_id].tx_dropped);
1909 if (record_burst_stats) {
1910 if (ports_stats[pt_id].rx_stream)
1911 pkt_burst_stats_display("RX",
1912 &ports_stats[pt_id].rx_stream->rx_burst_stats);
1913 if (ports_stats[pt_id].tx_stream)
1914 pkt_burst_stats_display("TX",
1915 &ports_stats[pt_id].tx_stream->tx_burst_stats);
1918 printf(" %s--------------------------------%s\n",
1919 fwd_stats_border, fwd_stats_border);
1922 printf("\n %s Accumulated forward statistics for all ports"
1924 acc_stats_border, acc_stats_border);
1925 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1927 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1929 total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1930 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1931 if (total_rx_nombuf > 0)
1932 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1933 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++"
1935 acc_stats_border, acc_stats_border);
1936 if (record_core_cycles) {
1937 #define CYC_PER_MHZ 1E6
1938 if (total_recv > 0 || total_xmit > 0) {
1939 uint64_t total_pkts = 0;
1940 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 ||
1941 strcmp(cur_fwd_eng->fwd_mode_name, "flowgen") == 0)
1942 total_pkts = total_xmit;
1944 total_pkts = total_recv;
1946 printf("\n CPU cycles/packet=%.2F (total cycles="
1947 "%"PRIu64" / total %s packets=%"PRIu64") at %"PRIu64
1949 (double) fwd_cycles / total_pkts,
1950 fwd_cycles, cur_fwd_eng->fwd_mode_name, total_pkts,
1951 (uint64_t)(rte_get_tsc_hz() / CYC_PER_MHZ));
1957 fwd_stats_reset(void)
1963 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1964 pt_id = fwd_ports_ids[i];
1965 rte_eth_stats_get(pt_id, &ports[pt_id].stats);
1967 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1968 struct fwd_stream *fs = fwd_streams[sm_id];
1972 fs->fwd_dropped = 0;
1973 fs->rx_bad_ip_csum = 0;
1974 fs->rx_bad_l4_csum = 0;
1975 fs->rx_bad_outer_l4_csum = 0;
1976 fs->rx_bad_outer_ip_csum = 0;
1978 memset(&fs->rx_burst_stats, 0, sizeof(fs->rx_burst_stats));
1979 memset(&fs->tx_burst_stats, 0, sizeof(fs->tx_burst_stats));
1980 fs->core_cycles = 0;
1985 flush_fwd_rx_queues(void)
1987 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1994 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1995 uint64_t timer_period;
1997 /* convert to number of cycles */
1998 timer_period = rte_get_timer_hz(); /* 1 second timeout */
2000 for (j = 0; j < 2; j++) {
2001 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
2002 for (rxq = 0; rxq < nb_rxq; rxq++) {
2003 port_id = fwd_ports_ids[rxp];
2005 * testpmd can stuck in the below do while loop
2006 * if rte_eth_rx_burst() always returns nonzero
2007 * packets. So timer is added to exit this loop
2008 * after 1sec timer expiry.
2010 prev_tsc = rte_rdtsc();
2012 nb_rx = rte_eth_rx_burst(port_id, rxq,
2013 pkts_burst, MAX_PKT_BURST);
2014 for (i = 0; i < nb_rx; i++)
2015 rte_pktmbuf_free(pkts_burst[i]);
2017 cur_tsc = rte_rdtsc();
2018 diff_tsc = cur_tsc - prev_tsc;
2019 timer_tsc += diff_tsc;
2020 } while ((nb_rx > 0) &&
2021 (timer_tsc < timer_period));
2025 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
2030 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
2032 struct fwd_stream **fsm;
2035 #ifdef RTE_LIB_BITRATESTATS
2036 uint64_t tics_per_1sec;
2037 uint64_t tics_datum;
2038 uint64_t tics_current;
2039 uint16_t i, cnt_ports;
2041 cnt_ports = nb_ports;
2042 tics_datum = rte_rdtsc();
2043 tics_per_1sec = rte_get_timer_hz();
2045 fsm = &fwd_streams[fc->stream_idx];
2046 nb_fs = fc->stream_nb;
2048 for (sm_id = 0; sm_id < nb_fs; sm_id++)
2049 (*pkt_fwd)(fsm[sm_id]);
2050 #ifdef RTE_LIB_BITRATESTATS
2051 if (bitrate_enabled != 0 &&
2052 bitrate_lcore_id == rte_lcore_id()) {
2053 tics_current = rte_rdtsc();
2054 if (tics_current - tics_datum >= tics_per_1sec) {
2055 /* Periodic bitrate calculation */
2056 for (i = 0; i < cnt_ports; i++)
2057 rte_stats_bitrate_calc(bitrate_data,
2059 tics_datum = tics_current;
2063 #ifdef RTE_LIB_LATENCYSTATS
2064 if (latencystats_enabled != 0 &&
2065 latencystats_lcore_id == rte_lcore_id())
2066 rte_latencystats_update();
2069 } while (! fc->stopped);
2073 start_pkt_forward_on_core(void *fwd_arg)
2075 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
2076 cur_fwd_config.fwd_eng->packet_fwd);
2081 * Run the TXONLY packet forwarding engine to send a single burst of packets.
2082 * Used to start communication flows in network loopback test configurations.
2085 run_one_txonly_burst_on_core(void *fwd_arg)
2087 struct fwd_lcore *fwd_lc;
2088 struct fwd_lcore tmp_lcore;
2090 fwd_lc = (struct fwd_lcore *) fwd_arg;
2091 tmp_lcore = *fwd_lc;
2092 tmp_lcore.stopped = 1;
2093 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
2098 * Launch packet forwarding:
2099 * - Setup per-port forwarding context.
2100 * - launch logical cores with their forwarding configuration.
2103 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
2105 port_fwd_begin_t port_fwd_begin;
2110 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
2111 if (port_fwd_begin != NULL) {
2112 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2113 (*port_fwd_begin)(fwd_ports_ids[i]);
2115 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
2116 lc_id = fwd_lcores_cpuids[i];
2117 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
2118 fwd_lcores[i]->stopped = 0;
2119 diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
2120 fwd_lcores[i], lc_id);
2122 printf("launch lcore %u failed - diag=%d\n",
2129 * Launch packet forwarding configuration.
2132 start_packet_forwarding(int with_tx_first)
2134 port_fwd_begin_t port_fwd_begin;
2135 port_fwd_end_t port_fwd_end;
2136 struct rte_port *port;
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 printf("Not all ports were started\n");
2157 if (test_done == 0) {
2158 printf("Packet forwarding already started\n");
2164 for (i = 0; i < nb_fwd_ports; i++) {
2165 pt_id = fwd_ports_ids[i];
2166 port = &ports[pt_id];
2167 if (!port->dcb_flag) {
2168 printf("In DCB mode, all forwarding ports must "
2169 "be configured in this mode.\n");
2173 if (nb_fwd_lcores == 1) {
2174 printf("In DCB mode,the nb forwarding cores "
2175 "should be larger than 1.\n");
2184 flush_fwd_rx_queues();
2186 pkt_fwd_config_display(&cur_fwd_config);
2187 rxtx_config_display();
2190 if (with_tx_first) {
2191 port_fwd_begin = tx_only_engine.port_fwd_begin;
2192 if (port_fwd_begin != NULL) {
2193 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2194 (*port_fwd_begin)(fwd_ports_ids[i]);
2196 while (with_tx_first--) {
2197 launch_packet_forwarding(
2198 run_one_txonly_burst_on_core);
2199 rte_eal_mp_wait_lcore();
2201 port_fwd_end = tx_only_engine.port_fwd_end;
2202 if (port_fwd_end != NULL) {
2203 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2204 (*port_fwd_end)(fwd_ports_ids[i]);
2207 launch_packet_forwarding(start_pkt_forward_on_core);
2211 stop_packet_forwarding(void)
2213 port_fwd_end_t port_fwd_end;
2219 printf("Packet forwarding not started\n");
2222 printf("Telling cores to stop...");
2223 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
2224 fwd_lcores[lc_id]->stopped = 1;
2225 printf("\nWaiting for lcores to finish...\n");
2226 rte_eal_mp_wait_lcore();
2227 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
2228 if (port_fwd_end != NULL) {
2229 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
2230 pt_id = fwd_ports_ids[i];
2231 (*port_fwd_end)(pt_id);
2235 fwd_stats_display();
2237 printf("\nDone.\n");
2242 dev_set_link_up(portid_t pid)
2244 if (rte_eth_dev_set_link_up(pid) < 0)
2245 printf("\nSet link up fail.\n");
2249 dev_set_link_down(portid_t pid)
2251 if (rte_eth_dev_set_link_down(pid) < 0)
2252 printf("\nSet link down fail.\n");
2256 all_ports_started(void)
2259 struct rte_port *port;
2261 RTE_ETH_FOREACH_DEV(pi) {
2263 /* Check if there is a port which is not started */
2264 if ((port->port_status != RTE_PORT_STARTED) &&
2265 (port->slave_flag == 0))
2269 /* No port is not started */
2274 port_is_stopped(portid_t port_id)
2276 struct rte_port *port = &ports[port_id];
2278 if ((port->port_status != RTE_PORT_STOPPED) &&
2279 (port->slave_flag == 0))
2285 all_ports_stopped(void)
2289 RTE_ETH_FOREACH_DEV(pi) {
2290 if (!port_is_stopped(pi))
2298 port_is_started(portid_t port_id)
2300 if (port_id_is_invalid(port_id, ENABLED_WARN))
2303 if (ports[port_id].port_status != RTE_PORT_STARTED)
2309 /* Configure the Rx and Tx hairpin queues for the selected port. */
2311 setup_hairpin_queues(portid_t pi, portid_t p_pi, uint16_t cnt_pi)
2314 struct rte_eth_hairpin_conf hairpin_conf = {
2319 struct rte_port *port = &ports[pi];
2320 uint16_t peer_rx_port = pi;
2321 uint16_t peer_tx_port = pi;
2322 uint32_t manual = 1;
2323 uint32_t tx_exp = hairpin_mode & 0x10;
2325 if (!(hairpin_mode & 0xf)) {
2329 } else if (hairpin_mode & 0x1) {
2330 peer_tx_port = rte_eth_find_next_owned_by(pi + 1,
2331 RTE_ETH_DEV_NO_OWNER);
2332 if (peer_tx_port >= RTE_MAX_ETHPORTS)
2333 peer_tx_port = rte_eth_find_next_owned_by(0,
2334 RTE_ETH_DEV_NO_OWNER);
2335 if (p_pi != RTE_MAX_ETHPORTS) {
2336 peer_rx_port = p_pi;
2340 /* Last port will be the peer RX port of the first. */
2341 RTE_ETH_FOREACH_DEV(next_pi)
2342 peer_rx_port = next_pi;
2345 } else if (hairpin_mode & 0x2) {
2347 peer_rx_port = p_pi;
2349 peer_rx_port = rte_eth_find_next_owned_by(pi + 1,
2350 RTE_ETH_DEV_NO_OWNER);
2351 if (peer_rx_port >= RTE_MAX_ETHPORTS)
2354 peer_tx_port = peer_rx_port;
2358 for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) {
2359 hairpin_conf.peers[0].port = peer_rx_port;
2360 hairpin_conf.peers[0].queue = i + nb_rxq;
2361 hairpin_conf.manual_bind = !!manual;
2362 hairpin_conf.tx_explicit = !!tx_exp;
2363 diag = rte_eth_tx_hairpin_queue_setup
2364 (pi, qi, nb_txd, &hairpin_conf);
2369 /* Fail to setup rx queue, return */
2370 if (rte_atomic16_cmpset(&(port->port_status),
2372 RTE_PORT_STOPPED) == 0)
2373 printf("Port %d can not be set back "
2374 "to stopped\n", pi);
2375 printf("Fail to configure port %d hairpin "
2377 /* try to reconfigure queues next time */
2378 port->need_reconfig_queues = 1;
2381 for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) {
2382 hairpin_conf.peers[0].port = peer_tx_port;
2383 hairpin_conf.peers[0].queue = i + nb_txq;
2384 hairpin_conf.manual_bind = !!manual;
2385 hairpin_conf.tx_explicit = !!tx_exp;
2386 diag = rte_eth_rx_hairpin_queue_setup
2387 (pi, qi, nb_rxd, &hairpin_conf);
2392 /* Fail to setup rx queue, return */
2393 if (rte_atomic16_cmpset(&(port->port_status),
2395 RTE_PORT_STOPPED) == 0)
2396 printf("Port %d can not be set back "
2397 "to stopped\n", pi);
2398 printf("Fail to configure port %d hairpin "
2400 /* try to reconfigure queues next time */
2401 port->need_reconfig_queues = 1;
2407 /* Configure the Rx with optional split. */
2409 rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
2410 uint16_t nb_rx_desc, unsigned int socket_id,
2411 struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
2413 union rte_eth_rxseg rx_useg[MAX_SEGS_BUFFER_SPLIT] = {};
2414 unsigned int i, mp_n;
2417 if (rx_pkt_nb_segs <= 1 ||
2418 (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0) {
2419 rx_conf->rx_seg = NULL;
2420 rx_conf->rx_nseg = 0;
2421 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id,
2422 nb_rx_desc, socket_id,
2426 for (i = 0; i < rx_pkt_nb_segs; i++) {
2427 struct rte_eth_rxseg_split *rx_seg = &rx_useg[i].split;
2428 struct rte_mempool *mpx;
2430 * Use last valid pool for the segments with number
2431 * exceeding the pool index.
2433 mp_n = (i > mbuf_data_size_n) ? mbuf_data_size_n - 1 : i;
2434 mpx = mbuf_pool_find(socket_id, mp_n);
2435 /* Handle zero as mbuf data buffer size. */
2436 rx_seg->length = rx_pkt_seg_lengths[i] ?
2437 rx_pkt_seg_lengths[i] :
2438 mbuf_data_size[mp_n];
2439 rx_seg->offset = i < rx_pkt_nb_offs ?
2440 rx_pkt_seg_offsets[i] : 0;
2441 rx_seg->mp = mpx ? mpx : mp;
2443 rx_conf->rx_nseg = rx_pkt_nb_segs;
2444 rx_conf->rx_seg = rx_useg;
2445 ret = rte_eth_rx_queue_setup(port_id, rx_queue_id, nb_rx_desc,
2446 socket_id, rx_conf, NULL);
2447 rx_conf->rx_seg = NULL;
2448 rx_conf->rx_nseg = 0;
2453 start_port(portid_t pid)
2455 int diag, need_check_link_status = -1;
2457 portid_t p_pi = RTE_MAX_ETHPORTS;
2458 portid_t pl[RTE_MAX_ETHPORTS];
2459 portid_t peer_pl[RTE_MAX_ETHPORTS];
2460 uint16_t cnt_pi = 0;
2461 uint16_t cfg_pi = 0;
2464 struct rte_port *port;
2465 struct rte_ether_addr mac_addr;
2466 struct rte_eth_hairpin_cap cap;
2468 if (port_id_is_invalid(pid, ENABLED_WARN))
2473 RTE_ETH_FOREACH_DEV(pi) {
2474 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2477 need_check_link_status = 0;
2479 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
2480 RTE_PORT_HANDLING) == 0) {
2481 printf("Port %d is now not stopped\n", pi);
2485 if (port->need_reconfig > 0) {
2486 port->need_reconfig = 0;
2488 if (flow_isolate_all) {
2489 int ret = port_flow_isolate(pi, 1);
2491 printf("Failed to apply isolated"
2492 " mode on port %d\n", pi);
2496 configure_rxtx_dump_callbacks(0);
2497 printf("Configuring Port %d (socket %u)\n", pi,
2499 if (nb_hairpinq > 0 &&
2500 rte_eth_dev_hairpin_capability_get(pi, &cap)) {
2501 printf("Port %d doesn't support hairpin "
2505 /* configure port */
2506 diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq,
2507 nb_txq + nb_hairpinq,
2510 if (rte_atomic16_cmpset(&(port->port_status),
2511 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2512 printf("Port %d can not be set back "
2513 "to stopped\n", pi);
2514 printf("Fail to configure port %d\n", pi);
2515 /* try to reconfigure port next time */
2516 port->need_reconfig = 1;
2520 if (port->need_reconfig_queues > 0) {
2521 port->need_reconfig_queues = 0;
2522 /* setup tx queues */
2523 for (qi = 0; qi < nb_txq; qi++) {
2524 if ((numa_support) &&
2525 (txring_numa[pi] != NUMA_NO_CONFIG))
2526 diag = rte_eth_tx_queue_setup(pi, qi,
2527 port->nb_tx_desc[qi],
2529 &(port->tx_conf[qi]));
2531 diag = rte_eth_tx_queue_setup(pi, qi,
2532 port->nb_tx_desc[qi],
2534 &(port->tx_conf[qi]));
2539 /* Fail to setup tx queue, return */
2540 if (rte_atomic16_cmpset(&(port->port_status),
2542 RTE_PORT_STOPPED) == 0)
2543 printf("Port %d can not be set back "
2544 "to stopped\n", pi);
2545 printf("Fail to configure port %d tx queues\n",
2547 /* try to reconfigure queues next time */
2548 port->need_reconfig_queues = 1;
2551 for (qi = 0; qi < nb_rxq; qi++) {
2552 /* setup rx queues */
2553 if ((numa_support) &&
2554 (rxring_numa[pi] != NUMA_NO_CONFIG)) {
2555 struct rte_mempool * mp =
2557 (rxring_numa[pi], 0);
2559 printf("Failed to setup RX queue:"
2560 "No mempool allocation"
2561 " on the socket %d\n",
2566 diag = rx_queue_setup(pi, qi,
2567 port->nb_rx_desc[qi],
2569 &(port->rx_conf[qi]),
2572 struct rte_mempool *mp =
2574 (port->socket_id, 0);
2576 printf("Failed to setup RX queue:"
2577 "No mempool allocation"
2578 " on the socket %d\n",
2582 diag = rx_queue_setup(pi, qi,
2583 port->nb_rx_desc[qi],
2585 &(port->rx_conf[qi]),
2591 /* Fail to setup rx queue, return */
2592 if (rte_atomic16_cmpset(&(port->port_status),
2594 RTE_PORT_STOPPED) == 0)
2595 printf("Port %d can not be set back "
2596 "to stopped\n", pi);
2597 printf("Fail to configure port %d rx queues\n",
2599 /* try to reconfigure queues next time */
2600 port->need_reconfig_queues = 1;
2603 /* setup hairpin queues */
2604 if (setup_hairpin_queues(pi, p_pi, cnt_pi) != 0)
2607 configure_rxtx_dump_callbacks(verbose_level);
2609 diag = rte_eth_dev_set_ptypes(pi, RTE_PTYPE_UNKNOWN,
2613 "Port %d: Failed to disable Ptype parsing\n",
2621 if (rte_eth_dev_start(pi) < 0) {
2622 printf("Fail to start port %d\n", pi);
2624 /* Fail to setup rx queue, return */
2625 if (rte_atomic16_cmpset(&(port->port_status),
2626 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2627 printf("Port %d can not be set back to "
2632 if (rte_atomic16_cmpset(&(port->port_status),
2633 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2634 printf("Port %d can not be set into started\n", pi);
2636 if (eth_macaddr_get_print_err(pi, &mac_addr) == 0)
2637 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2638 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
2639 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
2640 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
2642 /* at least one port started, need checking link status */
2643 need_check_link_status = 1;
2648 if (need_check_link_status == 1 && !no_link_check)
2649 check_all_ports_link_status(RTE_PORT_ALL);
2650 else if (need_check_link_status == 0)
2651 printf("Please stop the ports first\n");
2653 if (hairpin_mode & 0xf) {
2657 /* bind all started hairpin ports */
2658 for (i = 0; i < cfg_pi; i++) {
2660 /* bind current Tx to all peer Rx */
2661 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2662 RTE_MAX_ETHPORTS, 1);
2665 for (j = 0; j < peer_pi; j++) {
2666 if (!port_is_started(peer_pl[j]))
2668 diag = rte_eth_hairpin_bind(pi, peer_pl[j]);
2670 printf("Error during binding hairpin"
2671 " Tx port %u to %u: %s\n",
2673 rte_strerror(-diag));
2677 /* bind all peer Tx to current Rx */
2678 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2679 RTE_MAX_ETHPORTS, 0);
2682 for (j = 0; j < peer_pi; j++) {
2683 if (!port_is_started(peer_pl[j]))
2685 diag = rte_eth_hairpin_bind(peer_pl[j], pi);
2687 printf("Error during binding hairpin"
2688 " Tx port %u to %u: %s\n",
2690 rte_strerror(-diag));
2702 stop_port(portid_t pid)
2705 struct rte_port *port;
2706 int need_check_link_status = 0;
2707 portid_t peer_pl[RTE_MAX_ETHPORTS];
2715 if (port_id_is_invalid(pid, ENABLED_WARN))
2718 printf("Stopping ports...\n");
2720 RTE_ETH_FOREACH_DEV(pi) {
2721 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2724 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2725 printf("Please remove port %d from forwarding configuration.\n", pi);
2729 if (port_is_bonding_slave(pi)) {
2730 printf("Please remove port %d from bonded device.\n", pi);
2735 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
2736 RTE_PORT_HANDLING) == 0)
2739 if (hairpin_mode & 0xf) {
2742 rte_eth_hairpin_unbind(pi, RTE_MAX_ETHPORTS);
2743 /* unbind all peer Tx from current Rx */
2744 peer_pi = rte_eth_hairpin_get_peer_ports(pi, peer_pl,
2745 RTE_MAX_ETHPORTS, 0);
2748 for (j = 0; j < peer_pi; j++) {
2749 if (!port_is_started(peer_pl[j]))
2751 rte_eth_hairpin_unbind(peer_pl[j], pi);
2755 if (port->flow_list)
2756 port_flow_flush(pi);
2758 if (rte_eth_dev_stop(pi) != 0)
2759 RTE_LOG(ERR, EAL, "rte_eth_dev_stop failed for port %u\n",
2762 if (rte_atomic16_cmpset(&(port->port_status),
2763 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2764 printf("Port %d can not be set into stopped\n", pi);
2765 need_check_link_status = 1;
2767 if (need_check_link_status && !no_link_check)
2768 check_all_ports_link_status(RTE_PORT_ALL);
2774 remove_invalid_ports_in(portid_t *array, portid_t *total)
2777 portid_t new_total = 0;
2779 for (i = 0; i < *total; i++)
2780 if (!port_id_is_invalid(array[i], DISABLED_WARN)) {
2781 array[new_total] = array[i];
2788 remove_invalid_ports(void)
2790 remove_invalid_ports_in(ports_ids, &nb_ports);
2791 remove_invalid_ports_in(fwd_ports_ids, &nb_fwd_ports);
2792 nb_cfg_ports = nb_fwd_ports;
2796 close_port(portid_t pid)
2799 struct rte_port *port;
2801 if (port_id_is_invalid(pid, ENABLED_WARN))
2804 printf("Closing ports...\n");
2806 RTE_ETH_FOREACH_DEV(pi) {
2807 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2810 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2811 printf("Please remove port %d from forwarding configuration.\n", pi);
2815 if (port_is_bonding_slave(pi)) {
2816 printf("Please remove port %d from bonded device.\n", pi);
2821 if (rte_atomic16_cmpset(&(port->port_status),
2822 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2823 printf("Port %d is already closed\n", pi);
2827 port_flow_flush(pi);
2828 rte_eth_dev_close(pi);
2831 remove_invalid_ports();
2836 reset_port(portid_t pid)
2840 struct rte_port *port;
2842 if (port_id_is_invalid(pid, ENABLED_WARN))
2845 if ((pid == (portid_t)RTE_PORT_ALL && !all_ports_stopped()) ||
2846 (pid != (portid_t)RTE_PORT_ALL && !port_is_stopped(pid))) {
2847 printf("Can not reset port(s), please stop port(s) first.\n");
2851 printf("Resetting ports...\n");
2853 RTE_ETH_FOREACH_DEV(pi) {
2854 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2857 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2858 printf("Please remove port %d from forwarding "
2859 "configuration.\n", pi);
2863 if (port_is_bonding_slave(pi)) {
2864 printf("Please remove port %d from bonded device.\n",
2869 diag = rte_eth_dev_reset(pi);
2872 port->need_reconfig = 1;
2873 port->need_reconfig_queues = 1;
2875 printf("Failed to reset port %d. diag=%d\n", pi, diag);
2883 attach_port(char *identifier)
2886 struct rte_dev_iterator iterator;
2888 printf("Attaching a new port...\n");
2890 if (identifier == NULL) {
2891 printf("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);
2932 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n",
2933 pi, rte_strerror(-ret));
2935 ports_ids[nb_ports++] = pi;
2936 fwd_ports_ids[nb_fwd_ports++] = pi;
2937 nb_cfg_ports = nb_fwd_ports;
2938 ports[pi].need_setup = 0;
2939 ports[pi].port_status = RTE_PORT_STOPPED;
2941 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2946 detach_device(struct rte_device *dev)
2951 printf("Device already removed\n");
2955 printf("Removing a device...\n");
2957 RTE_ETH_FOREACH_DEV_OF(sibling, dev) {
2958 if (ports[sibling].port_status != RTE_PORT_CLOSED) {
2959 if (ports[sibling].port_status != RTE_PORT_STOPPED) {
2960 printf("Port %u not stopped\n", sibling);
2963 port_flow_flush(sibling);
2967 if (rte_dev_remove(dev) < 0) {
2968 TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name);
2971 remove_invalid_ports();
2973 printf("Device is detached\n");
2974 printf("Now total ports is %d\n", nb_ports);
2980 detach_port_device(portid_t port_id)
2982 if (port_id_is_invalid(port_id, ENABLED_WARN))
2985 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
2986 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
2987 printf("Port not stopped\n");
2990 printf("Port was not closed\n");
2993 detach_device(rte_eth_devices[port_id].device);
2997 detach_devargs(char *identifier)
2999 struct rte_dev_iterator iterator;
3000 struct rte_devargs da;
3003 printf("Removing a device...\n");
3005 memset(&da, 0, sizeof(da));
3006 if (rte_devargs_parsef(&da, "%s", identifier)) {
3007 printf("cannot parse identifier\n");
3013 RTE_ETH_FOREACH_MATCHING_DEV(port_id, identifier, &iterator) {
3014 if (ports[port_id].port_status != RTE_PORT_CLOSED) {
3015 if (ports[port_id].port_status != RTE_PORT_STOPPED) {
3016 printf("Port %u not stopped\n", port_id);
3017 rte_eth_iterator_cleanup(&iterator);
3020 port_flow_flush(port_id);
3024 if (rte_eal_hotplug_remove(da.bus->name, da.name) != 0) {
3025 TESTPMD_LOG(ERR, "Failed to detach device %s(%s)\n",
3026 da.name, da.bus->name);
3030 remove_invalid_ports();
3032 printf("Device %s is detached\n", identifier);
3033 printf("Now total ports is %d\n", nb_ports);
3045 stop_packet_forwarding();
3047 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3049 if (mp_alloc_type == MP_ALLOC_ANON)
3050 rte_mempool_mem_iter(mempools[i], dma_unmap_cb,
3054 if (ports != NULL) {
3056 RTE_ETH_FOREACH_DEV(pt_id) {
3057 printf("\nStopping port %d...\n", pt_id);
3061 RTE_ETH_FOREACH_DEV(pt_id) {
3062 printf("\nShutting down port %d...\n", pt_id);
3069 ret = rte_dev_event_monitor_stop();
3072 "fail to stop device event monitor.");
3076 ret = rte_dev_event_callback_unregister(NULL,
3077 dev_event_callback, NULL);
3080 "fail to unregister device event callback.\n");
3084 ret = rte_dev_hotplug_handle_disable();
3087 "fail to disable hotplug handling.\n");
3091 for (i = 0 ; i < RTE_DIM(mempools) ; i++) {
3093 rte_mempool_free(mempools[i]);
3096 printf("\nBye...\n");
3099 typedef void (*cmd_func_t)(void);
3100 struct pmd_test_command {
3101 const char *cmd_name;
3102 cmd_func_t cmd_func;
3105 /* Check the link status of all ports in up to 9s, and print them finally */
3107 check_all_ports_link_status(uint32_t port_mask)
3109 #define CHECK_INTERVAL 100 /* 100ms */
3110 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
3112 uint8_t count, all_ports_up, print_flag = 0;
3113 struct rte_eth_link link;
3115 char link_status[RTE_ETH_LINK_MAX_STR_LEN];
3117 printf("Checking link statuses...\n");
3119 for (count = 0; count <= MAX_CHECK_TIME; count++) {
3121 RTE_ETH_FOREACH_DEV(portid) {
3122 if ((port_mask & (1 << portid)) == 0)
3124 memset(&link, 0, sizeof(link));
3125 ret = rte_eth_link_get_nowait(portid, &link);
3128 if (print_flag == 1)
3129 printf("Port %u link get failed: %s\n",
3130 portid, rte_strerror(-ret));
3133 /* print link status if flag set */
3134 if (print_flag == 1) {
3135 rte_eth_link_to_str(link_status,
3136 sizeof(link_status), &link);
3137 printf("Port %d %s\n", portid, link_status);
3140 /* clear all_ports_up flag if any link down */
3141 if (link.link_status == ETH_LINK_DOWN) {
3146 /* after finally printing all link status, get out */
3147 if (print_flag == 1)
3150 if (all_ports_up == 0) {
3152 rte_delay_ms(CHECK_INTERVAL);
3155 /* set the print_flag if all ports up or timeout */
3156 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
3166 rmv_port_callback(void *arg)
3168 int need_to_start = 0;
3169 int org_no_link_check = no_link_check;
3170 portid_t port_id = (intptr_t)arg;
3171 struct rte_device *dev;
3173 RTE_ETH_VALID_PORTID_OR_RET(port_id);
3175 if (!test_done && port_is_forwarding(port_id)) {
3177 stop_packet_forwarding();
3181 no_link_check = org_no_link_check;
3183 /* Save rte_device pointer before closing ethdev port */
3184 dev = rte_eth_devices[port_id].device;
3185 close_port(port_id);
3186 detach_device(dev); /* might be already removed or have more ports */
3189 start_packet_forwarding(0);
3192 /* This function is used by the interrupt thread */
3194 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
3197 RTE_SET_USED(param);
3198 RTE_SET_USED(ret_param);
3200 if (type >= RTE_ETH_EVENT_MAX) {
3201 fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
3202 port_id, __func__, type);
3204 } else if (event_print_mask & (UINT32_C(1) << type)) {
3205 printf("\nPort %" PRIu16 ": %s event\n", port_id,
3206 eth_event_desc[type]);
3211 case RTE_ETH_EVENT_NEW:
3212 ports[port_id].need_setup = 1;
3213 ports[port_id].port_status = RTE_PORT_HANDLING;
3215 case RTE_ETH_EVENT_INTR_RMV:
3216 if (port_id_is_invalid(port_id, DISABLED_WARN))
3218 if (rte_eal_alarm_set(100000,
3219 rmv_port_callback, (void *)(intptr_t)port_id))
3220 fprintf(stderr, "Could not set up deferred device removal\n");
3222 case RTE_ETH_EVENT_DESTROY:
3223 ports[port_id].port_status = RTE_PORT_CLOSED;
3224 printf("Port %u is closed\n", port_id);
3233 register_eth_event_callback(void)
3236 enum rte_eth_event_type event;
3238 for (event = RTE_ETH_EVENT_UNKNOWN;
3239 event < RTE_ETH_EVENT_MAX; event++) {
3240 ret = rte_eth_dev_callback_register(RTE_ETH_ALL,
3245 TESTPMD_LOG(ERR, "Failed to register callback for "
3246 "%s event\n", eth_event_desc[event]);
3254 /* This function is used by the interrupt thread */
3256 dev_event_callback(const char *device_name, enum rte_dev_event_type type,
3257 __rte_unused void *arg)
3262 if (type >= RTE_DEV_EVENT_MAX) {
3263 fprintf(stderr, "%s called upon invalid event %d\n",
3269 case RTE_DEV_EVENT_REMOVE:
3270 RTE_LOG(DEBUG, EAL, "The device: %s has been removed!\n",
3272 ret = rte_eth_dev_get_port_by_name(device_name, &port_id);
3274 RTE_LOG(ERR, EAL, "can not get port by device %s!\n",
3279 * Because the user's callback is invoked in eal interrupt
3280 * callback, the interrupt callback need to be finished before
3281 * it can be unregistered when detaching device. So finish
3282 * callback soon and use a deferred removal to detach device
3283 * is need. It is a workaround, once the device detaching be
3284 * moved into the eal in the future, the deferred removal could
3287 if (rte_eal_alarm_set(100000,
3288 rmv_port_callback, (void *)(intptr_t)port_id))
3290 "Could not set up deferred device removal\n");
3292 case RTE_DEV_EVENT_ADD:
3293 RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
3295 /* TODO: After finish kernel driver binding,
3296 * begin to attach port.
3305 rxtx_port_config(struct rte_port *port)
3310 for (qid = 0; qid < nb_rxq; qid++) {
3311 offloads = port->rx_conf[qid].offloads;
3312 port->rx_conf[qid] = port->dev_info.default_rxconf;
3314 port->rx_conf[qid].offloads = offloads;
3316 /* Check if any Rx parameters have been passed */
3317 if (rx_pthresh != RTE_PMD_PARAM_UNSET)
3318 port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
3320 if (rx_hthresh != RTE_PMD_PARAM_UNSET)
3321 port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
3323 if (rx_wthresh != RTE_PMD_PARAM_UNSET)
3324 port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
3326 if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
3327 port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
3329 if (rx_drop_en != RTE_PMD_PARAM_UNSET)
3330 port->rx_conf[qid].rx_drop_en = rx_drop_en;
3332 port->nb_rx_desc[qid] = nb_rxd;
3335 for (qid = 0; qid < nb_txq; qid++) {
3336 offloads = port->tx_conf[qid].offloads;
3337 port->tx_conf[qid] = port->dev_info.default_txconf;
3339 port->tx_conf[qid].offloads = offloads;
3341 /* Check if any Tx parameters have been passed */
3342 if (tx_pthresh != RTE_PMD_PARAM_UNSET)
3343 port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
3345 if (tx_hthresh != RTE_PMD_PARAM_UNSET)
3346 port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
3348 if (tx_wthresh != RTE_PMD_PARAM_UNSET)
3349 port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
3351 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
3352 port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
3354 if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
3355 port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
3357 port->nb_tx_desc[qid] = nb_txd;
3362 * Helper function to arrange max_rx_pktlen value and JUMBO_FRAME offload,
3363 * MTU is also aligned if JUMBO_FRAME offload is not set.
3365 * port->dev_info should be set before calling this function.
3367 * return 0 on success, negative on error
3370 update_jumbo_frame_offload(portid_t portid)
3372 struct rte_port *port = &ports[portid];
3373 uint32_t eth_overhead;
3374 uint64_t rx_offloads;
3378 /* Update the max_rx_pkt_len to have MTU as RTE_ETHER_MTU */
3379 if (port->dev_info.max_mtu != UINT16_MAX &&
3380 port->dev_info.max_rx_pktlen > port->dev_info.max_mtu)
3381 eth_overhead = port->dev_info.max_rx_pktlen -
3382 port->dev_info.max_mtu;
3384 eth_overhead = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
3386 rx_offloads = port->dev_conf.rxmode.offloads;
3388 /* Default config value is 0 to use PMD specific overhead */
3389 if (port->dev_conf.rxmode.max_rx_pkt_len == 0)
3390 port->dev_conf.rxmode.max_rx_pkt_len = RTE_ETHER_MTU + eth_overhead;
3392 if (port->dev_conf.rxmode.max_rx_pkt_len <= RTE_ETHER_MTU + eth_overhead) {
3393 rx_offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3396 if ((port->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3397 printf("Frame size (%u) is not supported by port %u\n",
3398 port->dev_conf.rxmode.max_rx_pkt_len,
3402 rx_offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3406 if (rx_offloads != port->dev_conf.rxmode.offloads) {
3409 port->dev_conf.rxmode.offloads = rx_offloads;
3411 /* Apply JUMBO_FRAME offload configuration to Rx queue(s) */
3412 for (qid = 0; qid < port->dev_info.nb_rx_queues; qid++) {
3414 port->rx_conf[qid].offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
3416 port->rx_conf[qid].offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
3420 /* If JUMBO_FRAME is set MTU conversion done by ethdev layer,
3421 * if unset do it here
3423 if ((rx_offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) == 0) {
3424 ret = rte_eth_dev_set_mtu(portid,
3425 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead);
3427 printf("Failed to set MTU to %u for port %u\n",
3428 port->dev_conf.rxmode.max_rx_pkt_len - eth_overhead,
3436 init_port_config(void)
3439 struct rte_port *port;
3442 RTE_ETH_FOREACH_DEV(pid) {
3444 port->dev_conf.fdir_conf = fdir_conf;
3446 ret = eth_dev_info_get_print_err(pid, &port->dev_info);
3451 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3452 port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
3453 rss_hf & port->dev_info.flow_type_rss_offloads;
3455 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
3456 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
3459 if (port->dcb_flag == 0) {
3460 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
3461 port->dev_conf.rxmode.mq_mode =
3462 (enum rte_eth_rx_mq_mode)
3463 (rx_mq_mode & ETH_MQ_RX_RSS);
3465 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
3468 rxtx_port_config(port);
3470 ret = eth_macaddr_get_print_err(pid, &port->eth_addr);
3474 #if defined RTE_NET_IXGBE && defined RTE_LIBRTE_IXGBE_BYPASS
3475 rte_pmd_ixgbe_bypass_init(pid);
3478 if (lsc_interrupt &&
3479 (rte_eth_devices[pid].data->dev_flags &
3480 RTE_ETH_DEV_INTR_LSC))
3481 port->dev_conf.intr_conf.lsc = 1;
3482 if (rmv_interrupt &&
3483 (rte_eth_devices[pid].data->dev_flags &
3484 RTE_ETH_DEV_INTR_RMV))
3485 port->dev_conf.intr_conf.rmv = 1;
3489 void set_port_slave_flag(portid_t slave_pid)
3491 struct rte_port *port;
3493 port = &ports[slave_pid];
3494 port->slave_flag = 1;
3497 void clear_port_slave_flag(portid_t slave_pid)
3499 struct rte_port *port;
3501 port = &ports[slave_pid];
3502 port->slave_flag = 0;
3505 uint8_t port_is_bonding_slave(portid_t slave_pid)
3507 struct rte_port *port;
3509 port = &ports[slave_pid];
3510 if ((rte_eth_devices[slave_pid].data->dev_flags &
3511 RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
3516 const uint16_t vlan_tags[] = {
3517 0, 1, 2, 3, 4, 5, 6, 7,
3518 8, 9, 10, 11, 12, 13, 14, 15,
3519 16, 17, 18, 19, 20, 21, 22, 23,
3520 24, 25, 26, 27, 28, 29, 30, 31
3524 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
3525 enum dcb_mode_enable dcb_mode,
3526 enum rte_eth_nb_tcs num_tcs,
3531 struct rte_eth_rss_conf rss_conf;
3534 * Builds up the correct configuration for dcb+vt based on the vlan tags array
3535 * given above, and the number of traffic classes available for use.
3537 if (dcb_mode == DCB_VT_ENABLED) {
3538 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
3539 ð_conf->rx_adv_conf.vmdq_dcb_conf;
3540 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
3541 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf;
3543 /* VMDQ+DCB RX and TX configurations */
3544 vmdq_rx_conf->enable_default_pool = 0;
3545 vmdq_rx_conf->default_pool = 0;
3546 vmdq_rx_conf->nb_queue_pools =
3547 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3548 vmdq_tx_conf->nb_queue_pools =
3549 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
3551 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
3552 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
3553 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
3554 vmdq_rx_conf->pool_map[i].pools =
3555 1 << (i % vmdq_rx_conf->nb_queue_pools);
3557 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3558 vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
3559 vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
3562 /* set DCB mode of RX and TX of multiple queues */
3563 eth_conf->rxmode.mq_mode =
3564 (enum rte_eth_rx_mq_mode)
3565 (rx_mq_mode & ETH_MQ_RX_VMDQ_DCB);
3566 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
3568 struct rte_eth_dcb_rx_conf *rx_conf =
3569 ð_conf->rx_adv_conf.dcb_rx_conf;
3570 struct rte_eth_dcb_tx_conf *tx_conf =
3571 ð_conf->tx_adv_conf.dcb_tx_conf;
3573 memset(&rss_conf, 0, sizeof(struct rte_eth_rss_conf));
3575 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
3579 rx_conf->nb_tcs = num_tcs;
3580 tx_conf->nb_tcs = num_tcs;
3582 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
3583 rx_conf->dcb_tc[i] = i % num_tcs;
3584 tx_conf->dcb_tc[i] = i % num_tcs;
3587 eth_conf->rxmode.mq_mode =
3588 (enum rte_eth_rx_mq_mode)
3589 (rx_mq_mode & ETH_MQ_RX_DCB_RSS);
3590 eth_conf->rx_adv_conf.rss_conf = rss_conf;
3591 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
3595 eth_conf->dcb_capability_en =
3596 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
3598 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
3604 init_port_dcb_config(portid_t pid,
3605 enum dcb_mode_enable dcb_mode,
3606 enum rte_eth_nb_tcs num_tcs,
3609 struct rte_eth_conf port_conf;
3610 struct rte_port *rte_port;
3614 rte_port = &ports[pid];
3616 memset(&port_conf, 0, sizeof(struct rte_eth_conf));
3617 /* Enter DCB configuration status */
3620 port_conf.rxmode = rte_port->dev_conf.rxmode;
3621 port_conf.txmode = rte_port->dev_conf.txmode;
3623 /*set configuration of DCB in vt mode and DCB in non-vt mode*/
3624 retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
3627 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3629 /* re-configure the device . */
3630 retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
3634 retval = eth_dev_info_get_print_err(pid, &rte_port->dev_info);
3638 /* If dev_info.vmdq_pool_base is greater than 0,
3639 * the queue id of vmdq pools is started after pf queues.
3641 if (dcb_mode == DCB_VT_ENABLED &&
3642 rte_port->dev_info.vmdq_pool_base > 0) {
3643 printf("VMDQ_DCB multi-queue mode is nonsensical"
3644 " for port %d.", pid);
3648 /* Assume the ports in testpmd have the same dcb capability
3649 * and has the same number of rxq and txq in dcb mode
3651 if (dcb_mode == DCB_VT_ENABLED) {
3652 if (rte_port->dev_info.max_vfs > 0) {
3653 nb_rxq = rte_port->dev_info.nb_rx_queues;
3654 nb_txq = rte_port->dev_info.nb_tx_queues;
3656 nb_rxq = rte_port->dev_info.max_rx_queues;
3657 nb_txq = rte_port->dev_info.max_tx_queues;
3660 /*if vt is disabled, use all pf queues */
3661 if (rte_port->dev_info.vmdq_pool_base == 0) {
3662 nb_rxq = rte_port->dev_info.max_rx_queues;
3663 nb_txq = rte_port->dev_info.max_tx_queues;
3665 nb_rxq = (queueid_t)num_tcs;
3666 nb_txq = (queueid_t)num_tcs;
3670 rx_free_thresh = 64;
3672 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
3674 rxtx_port_config(rte_port);
3676 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
3677 for (i = 0; i < RTE_DIM(vlan_tags); i++)
3678 rx_vft_set(pid, vlan_tags[i], 1);
3680 retval = eth_macaddr_get_print_err(pid, &rte_port->eth_addr);
3684 rte_port->dcb_flag = 1;
3694 /* Configuration of Ethernet ports. */
3695 ports = rte_zmalloc("testpmd: ports",
3696 sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
3697 RTE_CACHE_LINE_SIZE);
3698 if (ports == NULL) {
3699 rte_exit(EXIT_FAILURE,
3700 "rte_zmalloc(%d struct rte_port) failed\n",
3703 for (i = 0; i < RTE_MAX_ETHPORTS; i++)
3704 LIST_INIT(&ports[i].flow_tunnel_list);
3705 /* Initialize ports NUMA structures */
3706 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3707 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3708 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
3722 const char clr[] = { 27, '[', '2', 'J', '\0' };
3723 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
3725 /* Clear screen and move to top left */
3726 printf("%s%s", clr, top_left);
3728 printf("\nPort statistics ====================================");
3729 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
3730 nic_stats_display(fwd_ports_ids[i]);
3736 signal_handler(int signum)
3738 if (signum == SIGINT || signum == SIGTERM) {
3739 printf("\nSignal %d received, preparing to exit...\n",
3741 #ifdef RTE_LIB_PDUMP
3742 /* uninitialize packet capture framework */
3745 #ifdef RTE_LIB_LATENCYSTATS
3746 if (latencystats_enabled != 0)
3747 rte_latencystats_uninit();
3750 /* Set flag to indicate the force termination. */
3752 /* exit with the expected status */
3753 signal(signum, SIG_DFL);
3754 kill(getpid(), signum);
3759 main(int argc, char** argv)
3766 signal(SIGINT, signal_handler);
3767 signal(SIGTERM, signal_handler);
3769 testpmd_logtype = rte_log_register("testpmd");
3770 if (testpmd_logtype < 0)
3771 rte_exit(EXIT_FAILURE, "Cannot register log type");
3772 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3774 diag = rte_eal_init(argc, argv);
3776 rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n",
3777 rte_strerror(rte_errno));
3779 if (rte_eal_process_type() == RTE_PROC_SECONDARY)
3780 rte_exit(EXIT_FAILURE,
3781 "Secondary process type not supported.\n");
3783 ret = register_eth_event_callback();
3785 rte_exit(EXIT_FAILURE, "Cannot register for ethdev events");
3787 #ifdef RTE_LIB_PDUMP
3788 /* initialize packet capture framework */
3793 RTE_ETH_FOREACH_DEV(port_id) {
3794 ports_ids[count] = port_id;
3797 nb_ports = (portid_t) count;
3799 TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3801 /* allocate port structures, and init them */
3804 set_def_fwd_config();
3806 rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n"
3807 "Check the core mask argument\n");
3809 /* Bitrate/latency stats disabled by default */
3810 #ifdef RTE_LIB_BITRATESTATS
3811 bitrate_enabled = 0;
3813 #ifdef RTE_LIB_LATENCYSTATS
3814 latencystats_enabled = 0;
3817 /* on FreeBSD, mlockall() is disabled by default */
3818 #ifdef RTE_EXEC_ENV_FREEBSD
3827 launch_args_parse(argc, argv);
3829 if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3830 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3834 if (tx_first && interactive)
3835 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3836 "interactive mode.\n");
3838 if (tx_first && lsc_interrupt) {
3839 printf("Warning: lsc_interrupt needs to be off when "
3840 " using tx_first. Disabling.\n");
3844 if (!nb_rxq && !nb_txq)
3845 printf("Warning: Either rx or tx queues should be non-zero\n");
3847 if (nb_rxq > 1 && nb_rxq > nb_txq)
3848 printf("Warning: nb_rxq=%d enables RSS configuration, "
3849 "but nb_txq=%d will prevent to fully test it.\n",
3855 ret = rte_dev_hotplug_handle_enable();
3858 "fail to enable hotplug handling.");
3862 ret = rte_dev_event_monitor_start();
3865 "fail to start device event monitoring.");
3869 ret = rte_dev_event_callback_register(NULL,
3870 dev_event_callback, NULL);
3873 "fail to register device event callback\n");
3878 if (!no_device_start && start_port(RTE_PORT_ALL) != 0)
3879 rte_exit(EXIT_FAILURE, "Start ports failed\n");
3881 /* set all ports to promiscuous mode by default */
3882 RTE_ETH_FOREACH_DEV(port_id) {
3883 ret = rte_eth_promiscuous_enable(port_id);
3885 printf("Error during enabling promiscuous mode for port %u: %s - ignore\n",
3886 port_id, rte_strerror(-ret));
3889 /* Init metrics library */
3890 rte_metrics_init(rte_socket_id());
3892 #ifdef RTE_LIB_LATENCYSTATS
3893 if (latencystats_enabled != 0) {
3894 int ret = rte_latencystats_init(1, NULL);
3896 printf("Warning: latencystats init()"
3897 " returned error %d\n", ret);
3898 printf("Latencystats running on lcore %d\n",
3899 latencystats_lcore_id);
3903 /* Setup bitrate stats */
3904 #ifdef RTE_LIB_BITRATESTATS
3905 if (bitrate_enabled != 0) {
3906 bitrate_data = rte_stats_bitrate_create();
3907 if (bitrate_data == NULL)
3908 rte_exit(EXIT_FAILURE,
3909 "Could not allocate bitrate data.\n");
3910 rte_stats_bitrate_reg(bitrate_data);
3914 #ifdef RTE_LIB_CMDLINE
3915 if (strlen(cmdline_filename) != 0)
3916 cmdline_read_from_file(cmdline_filename);
3918 if (interactive == 1) {
3920 printf("Start automatic packet forwarding\n");
3921 start_packet_forwarding(0);
3933 printf("No commandline core given, start packet forwarding\n");
3934 start_packet_forwarding(tx_first);
3935 if (stats_period != 0) {
3936 uint64_t prev_time = 0, cur_time, diff_time = 0;
3937 uint64_t timer_period;
3939 /* Convert to number of cycles */
3940 timer_period = stats_period * rte_get_timer_hz();
3942 while (f_quit == 0) {
3943 cur_time = rte_get_timer_cycles();
3944 diff_time += cur_time - prev_time;
3946 if (diff_time >= timer_period) {
3948 /* Reset the timer */
3951 /* Sleep to avoid unnecessary checks */
3952 prev_time = cur_time;
3957 printf("Press enter to exit\n");
3958 rc = read(0, &c, 1);
3964 ret = rte_eal_cleanup();
3966 rte_exit(EXIT_FAILURE,
3967 "EAL cleanup failed: %s\n", strerror(-ret));
3969 return EXIT_SUCCESS;