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_malloc_heap.h>
31 #include <rte_memory.h>
32 #include <rte_memcpy.h>
33 #include <rte_launch.h>
35 #include <rte_alarm.h>
36 #include <rte_per_lcore.h>
37 #include <rte_lcore.h>
38 #include <rte_atomic.h>
39 #include <rte_branch_prediction.h>
40 #include <rte_mempool.h>
41 #include <rte_malloc.h>
43 #include <rte_mbuf_pool_ops.h>
44 #include <rte_interrupts.h>
46 #include <rte_ether.h>
47 #include <rte_ethdev.h>
49 #include <rte_string_fns.h>
50 #ifdef RTE_LIBRTE_IXGBE_PMD
51 #include <rte_pmd_ixgbe.h>
53 #ifdef RTE_LIBRTE_PDUMP
54 #include <rte_pdump.h>
57 #include <rte_metrics.h>
58 #ifdef RTE_LIBRTE_BITRATE
59 #include <rte_bitrate.h>
61 #ifdef RTE_LIBRTE_LATENCY_STATS
62 #include <rte_latencystats.h>
68 /* FreeBSD may not have MAP_HUGETLB (in fact, it probably doesn't) */
69 #define HUGE_FLAG (0x40000)
71 #define HUGE_FLAG MAP_HUGETLB
74 #ifndef MAP_HUGE_SHIFT
75 /* older kernels (or FreeBSD) will not have this define */
76 #define HUGE_SHIFT (26)
78 #define HUGE_SHIFT MAP_HUGE_SHIFT
81 #define EXTMEM_HEAP_NAME "extmem"
83 uint16_t verbose_level = 0; /**< Silent by default. */
84 int testpmd_logtype; /**< Log type for testpmd logs */
86 /* use master 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 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[] = {
181 #if defined RTE_LIBRTE_PMD_SOFTNIC
184 #ifdef RTE_LIBRTE_IEEE1588
185 &ieee1588_fwd_engine,
190 struct fwd_config cur_fwd_config;
191 struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */
192 uint32_t retry_enabled;
193 uint32_t burst_tx_delay_time = BURST_TX_WAIT_US;
194 uint32_t burst_tx_retry_num = BURST_TX_RETRIES;
196 uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */
197 uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if
198 * specified on command-line. */
199 uint16_t stats_period; /**< Period to show statistics (disabled by default) */
202 * In container, it cannot terminate the process which running with 'stats-period'
203 * option. Set flag to exit stats period loop after received SIGINT/SIGTERM.
208 * Configuration of packet segments used by the "txonly" processing engine.
210 uint16_t tx_pkt_length = TXONLY_DEF_PACKET_LEN; /**< TXONLY packet length. */
211 uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT] = {
212 TXONLY_DEF_PACKET_LEN,
214 uint8_t tx_pkt_nb_segs = 1; /**< Number of segments in TXONLY packets */
216 enum tx_pkt_split tx_pkt_split = TX_PKT_SPLIT_OFF;
217 /**< Split policy for packets to TX. */
219 uint16_t nb_pkt_per_burst = DEF_PKT_BURST; /**< Number of packets per burst. */
220 uint16_t mb_mempool_cache = DEF_MBUF_CACHE; /**< Size of mbuf mempool cache. */
222 /* current configuration is in DCB or not,0 means it is not in DCB mode */
223 uint8_t dcb_config = 0;
225 /* Whether the dcb is in testing status */
226 uint8_t dcb_test = 0;
229 * Configurable number of RX/TX queues.
231 queueid_t nb_rxq = 1; /**< Number of RX queues per port. */
232 queueid_t nb_txq = 1; /**< Number of TX queues per port. */
235 * Configurable number of RX/TX ring descriptors.
236 * Defaults are supplied by drivers via ethdev.
238 #define RTE_TEST_RX_DESC_DEFAULT 0
239 #define RTE_TEST_TX_DESC_DEFAULT 0
240 uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; /**< Number of RX descriptors. */
241 uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; /**< Number of TX descriptors. */
243 #define RTE_PMD_PARAM_UNSET -1
245 * Configurable values of RX and TX ring threshold registers.
248 int8_t rx_pthresh = RTE_PMD_PARAM_UNSET;
249 int8_t rx_hthresh = RTE_PMD_PARAM_UNSET;
250 int8_t rx_wthresh = RTE_PMD_PARAM_UNSET;
252 int8_t tx_pthresh = RTE_PMD_PARAM_UNSET;
253 int8_t tx_hthresh = RTE_PMD_PARAM_UNSET;
254 int8_t tx_wthresh = RTE_PMD_PARAM_UNSET;
257 * Configurable value of RX free threshold.
259 int16_t rx_free_thresh = RTE_PMD_PARAM_UNSET;
262 * Configurable value of RX drop enable.
264 int8_t rx_drop_en = RTE_PMD_PARAM_UNSET;
267 * Configurable value of TX free threshold.
269 int16_t tx_free_thresh = RTE_PMD_PARAM_UNSET;
272 * Configurable value of TX RS bit threshold.
274 int16_t tx_rs_thresh = RTE_PMD_PARAM_UNSET;
277 * Receive Side Scaling (RSS) configuration.
279 uint64_t rss_hf = ETH_RSS_IP; /* RSS IP by default. */
282 * Port topology configuration
284 uint16_t port_topology = PORT_TOPOLOGY_PAIRED; /* Ports are paired by default */
287 * Avoids to flush all the RX streams before starts forwarding.
289 uint8_t no_flush_rx = 0; /* flush by default */
292 * Flow API isolated mode.
294 uint8_t flow_isolate_all;
297 * Avoids to check link status when starting/stopping a port.
299 uint8_t no_link_check = 0; /* check by default */
302 * Enable link status change notification
304 uint8_t lsc_interrupt = 1; /* enabled by default */
307 * Enable device removal notification.
309 uint8_t rmv_interrupt = 1; /* enabled by default */
311 uint8_t hot_plug = 0; /**< hotplug disabled by default. */
314 * Display or mask ether events
315 * Default to all events except VF_MBOX
317 uint32_t event_print_mask = (UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN) |
318 (UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC) |
319 (UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE) |
320 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET) |
321 (UINT32_C(1) << RTE_ETH_EVENT_IPSEC) |
322 (UINT32_C(1) << RTE_ETH_EVENT_MACSEC) |
323 (UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV);
325 * Decide if all memory are locked for performance.
330 * NIC bypass mode configuration options.
333 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
334 /* The NIC bypass watchdog timeout. */
335 uint32_t bypass_timeout = RTE_PMD_IXGBE_BYPASS_TMT_OFF;
339 #ifdef RTE_LIBRTE_LATENCY_STATS
342 * Set when latency stats is enabled in the commandline
344 uint8_t latencystats_enabled;
347 * Lcore ID to serive latency statistics.
349 lcoreid_t latencystats_lcore_id = -1;
354 * Ethernet device configuration.
356 struct rte_eth_rxmode rx_mode = {
357 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
360 struct rte_eth_txmode tx_mode = {
361 .offloads = DEV_TX_OFFLOAD_MBUF_FAST_FREE,
364 struct rte_fdir_conf fdir_conf = {
365 .mode = RTE_FDIR_MODE_NONE,
366 .pballoc = RTE_FDIR_PBALLOC_64K,
367 .status = RTE_FDIR_REPORT_STATUS,
369 .vlan_tci_mask = 0xFFEF,
371 .src_ip = 0xFFFFFFFF,
372 .dst_ip = 0xFFFFFFFF,
375 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
376 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
378 .src_port_mask = 0xFFFF,
379 .dst_port_mask = 0xFFFF,
380 .mac_addr_byte_mask = 0xFF,
381 .tunnel_type_mask = 1,
382 .tunnel_id_mask = 0xFFFFFFFF,
387 volatile int test_done = 1; /* stop packet forwarding when set to 1. */
389 struct queue_stats_mappings tx_queue_stats_mappings_array[MAX_TX_QUEUE_STATS_MAPPINGS];
390 struct queue_stats_mappings rx_queue_stats_mappings_array[MAX_RX_QUEUE_STATS_MAPPINGS];
392 struct queue_stats_mappings *tx_queue_stats_mappings = tx_queue_stats_mappings_array;
393 struct queue_stats_mappings *rx_queue_stats_mappings = rx_queue_stats_mappings_array;
395 uint16_t nb_tx_queue_stats_mappings = 0;
396 uint16_t nb_rx_queue_stats_mappings = 0;
399 * Display zero values by default for xstats
401 uint8_t xstats_hide_zero;
403 unsigned int num_sockets = 0;
404 unsigned int socket_ids[RTE_MAX_NUMA_NODES];
406 #ifdef RTE_LIBRTE_BITRATE
407 /* Bitrate statistics */
408 struct rte_stats_bitrates *bitrate_data;
409 lcoreid_t bitrate_lcore_id;
410 uint8_t bitrate_enabled;
413 struct gro_status gro_ports[RTE_MAX_ETHPORTS];
414 uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES;
416 struct vxlan_encap_conf vxlan_encap_conf = {
419 .vni = "\x00\x00\x00",
421 .udp_dst = RTE_BE16(4789),
422 .ipv4_src = IPv4(127, 0, 0, 1),
423 .ipv4_dst = IPv4(255, 255, 255, 255),
424 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
425 "\x00\x00\x00\x00\x00\x00\x00\x01",
426 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
427 "\x00\x00\x00\x00\x00\x00\x11\x11",
429 .eth_src = "\x00\x00\x00\x00\x00\x00",
430 .eth_dst = "\xff\xff\xff\xff\xff\xff",
433 struct nvgre_encap_conf nvgre_encap_conf = {
436 .tni = "\x00\x00\x00",
437 .ipv4_src = IPv4(127, 0, 0, 1),
438 .ipv4_dst = IPv4(255, 255, 255, 255),
439 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00"
440 "\x00\x00\x00\x00\x00\x00\x00\x01",
441 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00"
442 "\x00\x00\x00\x00\x00\x00\x11\x11",
444 .eth_src = "\x00\x00\x00\x00\x00\x00",
445 .eth_dst = "\xff\xff\xff\xff\xff\xff",
448 /* Forward function declarations */
449 static void map_port_queue_stats_mapping_registers(portid_t pi,
450 struct rte_port *port);
451 static void check_all_ports_link_status(uint32_t port_mask);
452 static int eth_event_callback(portid_t port_id,
453 enum rte_eth_event_type type,
454 void *param, void *ret_param);
455 static void eth_dev_event_callback(char *device_name,
456 enum rte_dev_event_type type,
458 static int eth_dev_event_callback_register(void);
459 static int eth_dev_event_callback_unregister(void);
463 * Check if all the ports are started.
464 * If yes, return positive value. If not, return zero.
466 static int all_ports_started(void);
468 struct gso_status gso_ports[RTE_MAX_ETHPORTS];
469 uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN;
472 * Helper function to check if socket is already discovered.
473 * If yes, return positive value. If not, return zero.
476 new_socket_id(unsigned int socket_id)
480 for (i = 0; i < num_sockets; i++) {
481 if (socket_ids[i] == socket_id)
488 * Setup default configuration.
491 set_default_fwd_lcores_config(void)
495 unsigned int sock_num;
498 for (i = 0; i < RTE_MAX_LCORE; i++) {
499 if (!rte_lcore_is_enabled(i))
501 sock_num = rte_lcore_to_socket_id(i);
502 if (new_socket_id(sock_num)) {
503 if (num_sockets >= RTE_MAX_NUMA_NODES) {
504 rte_exit(EXIT_FAILURE,
505 "Total sockets greater than %u\n",
508 socket_ids[num_sockets++] = sock_num;
510 if (i == rte_get_master_lcore())
512 fwd_lcores_cpuids[nb_lc++] = i;
514 nb_lcores = (lcoreid_t) nb_lc;
515 nb_cfg_lcores = nb_lcores;
520 set_def_peer_eth_addrs(void)
524 for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
525 peer_eth_addrs[i].addr_bytes[0] = ETHER_LOCAL_ADMIN_ADDR;
526 peer_eth_addrs[i].addr_bytes[5] = i;
531 set_default_fwd_ports_config(void)
536 RTE_ETH_FOREACH_DEV(pt_id)
537 fwd_ports_ids[i++] = pt_id;
539 nb_cfg_ports = nb_ports;
540 nb_fwd_ports = nb_ports;
544 set_def_fwd_config(void)
546 set_default_fwd_lcores_config();
547 set_def_peer_eth_addrs();
548 set_default_fwd_ports_config();
551 /* extremely pessimistic estimation of memory required to create a mempool */
553 calc_mem_size(uint32_t nb_mbufs, uint32_t mbuf_sz, size_t pgsz, size_t *out)
555 unsigned int n_pages, mbuf_per_pg, leftover;
556 uint64_t total_mem, mbuf_mem, obj_sz;
558 /* there is no good way to predict how much space the mempool will
559 * occupy because it will allocate chunks on the fly, and some of those
560 * will come from default DPDK memory while some will come from our
561 * external memory, so just assume 128MB will be enough for everyone.
563 uint64_t hdr_mem = 128 << 20;
565 /* account for possible non-contiguousness */
566 obj_sz = rte_mempool_calc_obj_size(mbuf_sz, 0, NULL);
568 TESTPMD_LOG(ERR, "Object size is bigger than page size\n");
572 mbuf_per_pg = pgsz / obj_sz;
573 leftover = (nb_mbufs % mbuf_per_pg) > 0;
574 n_pages = (nb_mbufs / mbuf_per_pg) + leftover;
576 mbuf_mem = n_pages * pgsz;
578 total_mem = RTE_ALIGN(hdr_mem + mbuf_mem, pgsz);
580 if (total_mem > SIZE_MAX) {
581 TESTPMD_LOG(ERR, "Memory size too big\n");
584 *out = (size_t)total_mem;
589 static inline uint32_t
592 return (uint32_t)__builtin_ctzll(v);
595 static inline uint32_t
600 v = rte_align64pow2(v);
605 pagesz_flags(uint64_t page_sz)
607 /* as per mmap() manpage, all page sizes are log2 of page size
608 * shifted by MAP_HUGE_SHIFT
610 int log2 = log2_u64(page_sz);
612 return (log2 << HUGE_SHIFT);
616 alloc_mem(size_t memsz, size_t pgsz, bool huge)
621 /* allocate anonymous hugepages */
622 flags = MAP_ANONYMOUS | MAP_PRIVATE;
624 flags |= HUGE_FLAG | pagesz_flags(pgsz);
626 addr = mmap(NULL, memsz, PROT_READ | PROT_WRITE, flags, -1, 0);
627 if (addr == MAP_FAILED)
633 struct extmem_param {
637 rte_iova_t *iova_table;
638 unsigned int iova_table_len;
642 create_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, struct extmem_param *param,
645 uint64_t pgsizes[] = {RTE_PGSIZE_2M, RTE_PGSIZE_1G, /* x86_64, ARM */
646 RTE_PGSIZE_16M, RTE_PGSIZE_16G}; /* POWER */
647 unsigned int cur_page, n_pages, pgsz_idx;
648 size_t mem_sz, cur_pgsz;
649 rte_iova_t *iovas = NULL;
653 for (pgsz_idx = 0; pgsz_idx < RTE_DIM(pgsizes); pgsz_idx++) {
654 /* skip anything that is too big */
655 if (pgsizes[pgsz_idx] > SIZE_MAX)
658 cur_pgsz = pgsizes[pgsz_idx];
660 /* if we were told not to allocate hugepages, override */
662 cur_pgsz = sysconf(_SC_PAGESIZE);
664 ret = calc_mem_size(nb_mbufs, mbuf_sz, cur_pgsz, &mem_sz);
666 TESTPMD_LOG(ERR, "Cannot calculate memory size\n");
670 /* allocate our memory */
671 addr = alloc_mem(mem_sz, cur_pgsz, huge);
673 /* if we couldn't allocate memory with a specified page size,
674 * that doesn't mean we can't do it with other page sizes, so
680 /* store IOVA addresses for every page in this memory area */
681 n_pages = mem_sz / cur_pgsz;
683 iovas = malloc(sizeof(*iovas) * n_pages);
686 TESTPMD_LOG(ERR, "Cannot allocate memory for iova addresses\n");
689 /* lock memory if it's not huge pages */
693 /* populate IOVA addresses */
694 for (cur_page = 0; cur_page < n_pages; cur_page++) {
699 offset = cur_pgsz * cur_page;
700 cur = RTE_PTR_ADD(addr, offset);
702 /* touch the page before getting its IOVA */
703 *(volatile char *)cur = 0;
705 iova = rte_mem_virt2iova(cur);
707 iovas[cur_page] = iova;
712 /* if we couldn't allocate anything */
718 param->pgsz = cur_pgsz;
719 param->iova_table = iovas;
720 param->iova_table_len = n_pages;
727 munmap(addr, mem_sz);
733 setup_extmem(uint32_t nb_mbufs, uint32_t mbuf_sz, bool huge)
735 struct extmem_param param;
738 memset(¶m, 0, sizeof(param));
740 /* check if our heap exists */
741 socket_id = rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
743 /* create our heap */
744 ret = rte_malloc_heap_create(EXTMEM_HEAP_NAME);
746 TESTPMD_LOG(ERR, "Cannot create heap\n");
751 ret = create_extmem(nb_mbufs, mbuf_sz, ¶m, huge);
753 TESTPMD_LOG(ERR, "Cannot create memory area\n");
757 /* we now have a valid memory area, so add it to heap */
758 ret = rte_malloc_heap_memory_add(EXTMEM_HEAP_NAME,
759 param.addr, param.len, param.iova_table,
760 param.iova_table_len, param.pgsz);
762 /* when using VFIO, memory is automatically mapped for DMA by EAL */
764 /* not needed any more */
765 free(param.iova_table);
768 TESTPMD_LOG(ERR, "Cannot add memory to heap\n");
769 munmap(param.addr, param.len);
775 TESTPMD_LOG(DEBUG, "Allocated %zuMB of external memory\n",
782 * Configuration initialisation done once at init time.
785 mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
786 unsigned int socket_id)
788 char pool_name[RTE_MEMPOOL_NAMESIZE];
789 struct rte_mempool *rte_mp = NULL;
792 mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size;
793 mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name));
796 "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
797 pool_name, nb_mbuf, mbuf_seg_size, socket_id);
799 switch (mp_alloc_type) {
800 case MP_ALLOC_NATIVE:
802 /* wrapper to rte_mempool_create() */
803 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
804 rte_mbuf_best_mempool_ops());
805 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
806 mb_mempool_cache, 0, mbuf_seg_size, socket_id);
811 rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
812 mb_size, (unsigned int) mb_mempool_cache,
813 sizeof(struct rte_pktmbuf_pool_private),
818 if (rte_mempool_populate_anon(rte_mp) == 0) {
819 rte_mempool_free(rte_mp);
823 rte_pktmbuf_pool_init(rte_mp, NULL);
824 rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL);
828 case MP_ALLOC_XMEM_HUGE:
831 bool huge = mp_alloc_type == MP_ALLOC_XMEM_HUGE;
833 if (setup_extmem(nb_mbuf, mbuf_seg_size, huge) < 0)
834 rte_exit(EXIT_FAILURE, "Could not create external memory\n");
837 rte_malloc_heap_get_socket(EXTMEM_HEAP_NAME);
839 rte_exit(EXIT_FAILURE, "Could not get external memory socket ID\n");
841 TESTPMD_LOG(INFO, "preferred mempool ops selected: %s\n",
842 rte_mbuf_best_mempool_ops());
843 rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf,
844 mb_mempool_cache, 0, mbuf_seg_size,
850 rte_exit(EXIT_FAILURE, "Invalid mempool creation mode\n");
855 if (rte_mp == NULL) {
856 rte_exit(EXIT_FAILURE,
857 "Creation of mbuf pool for socket %u failed: %s\n",
858 socket_id, rte_strerror(rte_errno));
859 } else if (verbose_level > 0) {
860 rte_mempool_dump(stdout, rte_mp);
865 * Check given socket id is valid or not with NUMA mode,
866 * if valid, return 0, else return -1
869 check_socket_id(const unsigned int socket_id)
871 static int warning_once = 0;
873 if (new_socket_id(socket_id)) {
874 if (!warning_once && numa_support)
875 printf("Warning: NUMA should be configured manually by"
876 " using --port-numa-config and"
877 " --ring-numa-config parameters along with"
886 * Get the allowed maximum number of RX queues.
887 * *pid return the port id which has minimal value of
888 * max_rx_queues in all ports.
891 get_allowed_max_nb_rxq(portid_t *pid)
893 queueid_t allowed_max_rxq = MAX_QUEUE_ID;
895 struct rte_eth_dev_info dev_info;
897 RTE_ETH_FOREACH_DEV(pi) {
898 rte_eth_dev_info_get(pi, &dev_info);
899 if (dev_info.max_rx_queues < allowed_max_rxq) {
900 allowed_max_rxq = dev_info.max_rx_queues;
904 return allowed_max_rxq;
908 * Check input rxq is valid or not.
909 * If input rxq is not greater than any of maximum number
910 * of RX queues of all ports, it is valid.
911 * if valid, return 0, else return -1
914 check_nb_rxq(queueid_t rxq)
916 queueid_t allowed_max_rxq;
919 allowed_max_rxq = get_allowed_max_nb_rxq(&pid);
920 if (rxq > allowed_max_rxq) {
921 printf("Fail: input rxq (%u) can't be greater "
922 "than max_rx_queues (%u) of port %u\n",
932 * Get the allowed maximum number of TX queues.
933 * *pid return the port id which has minimal value of
934 * max_tx_queues in all ports.
937 get_allowed_max_nb_txq(portid_t *pid)
939 queueid_t allowed_max_txq = MAX_QUEUE_ID;
941 struct rte_eth_dev_info dev_info;
943 RTE_ETH_FOREACH_DEV(pi) {
944 rte_eth_dev_info_get(pi, &dev_info);
945 if (dev_info.max_tx_queues < allowed_max_txq) {
946 allowed_max_txq = dev_info.max_tx_queues;
950 return allowed_max_txq;
954 * Check input txq is valid or not.
955 * If input txq is not greater than any of maximum number
956 * of TX queues of all ports, it is valid.
957 * if valid, return 0, else return -1
960 check_nb_txq(queueid_t txq)
962 queueid_t allowed_max_txq;
965 allowed_max_txq = get_allowed_max_nb_txq(&pid);
966 if (txq > allowed_max_txq) {
967 printf("Fail: input txq (%u) can't be greater "
968 "than max_tx_queues (%u) of port %u\n",
981 struct rte_port *port;
982 struct rte_mempool *mbp;
983 unsigned int nb_mbuf_per_pool;
985 uint8_t port_per_socket[RTE_MAX_NUMA_NODES];
986 struct rte_gro_param gro_param;
990 memset(port_per_socket,0,RTE_MAX_NUMA_NODES);
993 memset(port_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
994 memset(rxring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
995 memset(txring_numa, NUMA_NO_CONFIG, RTE_MAX_ETHPORTS);
998 /* Configuration of logical cores. */
999 fwd_lcores = rte_zmalloc("testpmd: fwd_lcores",
1000 sizeof(struct fwd_lcore *) * nb_lcores,
1001 RTE_CACHE_LINE_SIZE);
1002 if (fwd_lcores == NULL) {
1003 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) "
1004 "failed\n", nb_lcores);
1006 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1007 fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore",
1008 sizeof(struct fwd_lcore),
1009 RTE_CACHE_LINE_SIZE);
1010 if (fwd_lcores[lc_id] == NULL) {
1011 rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) "
1014 fwd_lcores[lc_id]->cpuid_idx = lc_id;
1017 RTE_ETH_FOREACH_DEV(pid) {
1019 /* Apply default TxRx configuration for all ports */
1020 port->dev_conf.txmode = tx_mode;
1021 port->dev_conf.rxmode = rx_mode;
1022 rte_eth_dev_info_get(pid, &port->dev_info);
1024 if (!(port->dev_info.tx_offload_capa &
1025 DEV_TX_OFFLOAD_MBUF_FAST_FREE))
1026 port->dev_conf.txmode.offloads &=
1027 ~DEV_TX_OFFLOAD_MBUF_FAST_FREE;
1029 if (port_numa[pid] != NUMA_NO_CONFIG)
1030 port_per_socket[port_numa[pid]]++;
1032 uint32_t socket_id = rte_eth_dev_socket_id(pid);
1034 /* if socket_id is invalid, set to 0 */
1035 if (check_socket_id(socket_id) < 0)
1037 port_per_socket[socket_id]++;
1041 /* Apply Rx offloads configuration */
1042 for (k = 0; k < port->dev_info.max_rx_queues; k++)
1043 port->rx_conf[k].offloads =
1044 port->dev_conf.rxmode.offloads;
1045 /* Apply Tx offloads configuration */
1046 for (k = 0; k < port->dev_info.max_tx_queues; k++)
1047 port->tx_conf[k].offloads =
1048 port->dev_conf.txmode.offloads;
1050 /* set flag to initialize port/queue */
1051 port->need_reconfig = 1;
1052 port->need_reconfig_queues = 1;
1056 * Create pools of mbuf.
1057 * If NUMA support is disabled, create a single pool of mbuf in
1058 * socket 0 memory by default.
1059 * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1.
1061 * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and
1062 * nb_txd can be configured at run time.
1064 if (param_total_num_mbufs)
1065 nb_mbuf_per_pool = param_total_num_mbufs;
1067 nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX +
1068 (nb_lcores * mb_mempool_cache) +
1069 RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST;
1070 nb_mbuf_per_pool *= RTE_MAX_ETHPORTS;
1076 for (i = 0; i < num_sockets; i++)
1077 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1080 if (socket_num == UMA_NO_CONFIG)
1081 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0);
1083 mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool,
1089 gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
1090 DEV_TX_OFFLOAD_GRE_TNL_TSO | DEV_TX_OFFLOAD_UDP_TSO;
1092 * Records which Mbuf pool to use by each logical core, if needed.
1094 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1095 mbp = mbuf_pool_find(
1096 rte_lcore_to_socket_id(fwd_lcores_cpuids[lc_id]));
1099 mbp = mbuf_pool_find(0);
1100 fwd_lcores[lc_id]->mbp = mbp;
1101 /* initialize GSO context */
1102 fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp;
1103 fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp;
1104 fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types;
1105 fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN -
1107 fwd_lcores[lc_id]->gso_ctx.flag = 0;
1110 /* Configuration of packet forwarding streams. */
1111 if (init_fwd_streams() < 0)
1112 rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n");
1116 /* create a gro context for each lcore */
1117 gro_param.gro_types = RTE_GRO_TCP_IPV4;
1118 gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES;
1119 gro_param.max_item_per_flow = MAX_PKT_BURST;
1120 for (lc_id = 0; lc_id < nb_lcores; lc_id++) {
1121 gro_param.socket_id = rte_lcore_to_socket_id(
1122 fwd_lcores_cpuids[lc_id]);
1123 fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param);
1124 if (fwd_lcores[lc_id]->gro_ctx == NULL) {
1125 rte_exit(EXIT_FAILURE,
1126 "rte_gro_ctx_create() failed\n");
1130 #if defined RTE_LIBRTE_PMD_SOFTNIC
1131 if (strcmp(cur_fwd_eng->fwd_mode_name, "softnic") == 0) {
1132 RTE_ETH_FOREACH_DEV(pid) {
1134 const char *driver = port->dev_info.driver_name;
1136 if (strcmp(driver, "net_softnic") == 0)
1137 port->softport.fwd_lcore_arg = fwd_lcores;
1146 reconfig(portid_t new_port_id, unsigned socket_id)
1148 struct rte_port *port;
1150 /* Reconfiguration of Ethernet ports. */
1151 port = &ports[new_port_id];
1152 rte_eth_dev_info_get(new_port_id, &port->dev_info);
1154 /* set flag to initialize port/queue */
1155 port->need_reconfig = 1;
1156 port->need_reconfig_queues = 1;
1157 port->socket_id = socket_id;
1164 init_fwd_streams(void)
1167 struct rte_port *port;
1168 streamid_t sm_id, nb_fwd_streams_new;
1171 /* set socket id according to numa or not */
1172 RTE_ETH_FOREACH_DEV(pid) {
1174 if (nb_rxq > port->dev_info.max_rx_queues) {
1175 printf("Fail: nb_rxq(%d) is greater than "
1176 "max_rx_queues(%d)\n", nb_rxq,
1177 port->dev_info.max_rx_queues);
1180 if (nb_txq > port->dev_info.max_tx_queues) {
1181 printf("Fail: nb_txq(%d) is greater than "
1182 "max_tx_queues(%d)\n", nb_txq,
1183 port->dev_info.max_tx_queues);
1187 if (port_numa[pid] != NUMA_NO_CONFIG)
1188 port->socket_id = port_numa[pid];
1190 port->socket_id = rte_eth_dev_socket_id(pid);
1192 /* if socket_id is invalid, set to 0 */
1193 if (check_socket_id(port->socket_id) < 0)
1194 port->socket_id = 0;
1198 if (socket_num == UMA_NO_CONFIG)
1199 port->socket_id = 0;
1201 port->socket_id = socket_num;
1205 q = RTE_MAX(nb_rxq, nb_txq);
1207 printf("Fail: Cannot allocate fwd streams as number of queues is 0\n");
1210 nb_fwd_streams_new = (streamid_t)(nb_ports * q);
1211 if (nb_fwd_streams_new == nb_fwd_streams)
1214 if (fwd_streams != NULL) {
1215 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1216 if (fwd_streams[sm_id] == NULL)
1218 rte_free(fwd_streams[sm_id]);
1219 fwd_streams[sm_id] = NULL;
1221 rte_free(fwd_streams);
1226 nb_fwd_streams = nb_fwd_streams_new;
1227 if (nb_fwd_streams) {
1228 fwd_streams = rte_zmalloc("testpmd: fwd_streams",
1229 sizeof(struct fwd_stream *) * nb_fwd_streams,
1230 RTE_CACHE_LINE_SIZE);
1231 if (fwd_streams == NULL)
1232 rte_exit(EXIT_FAILURE, "rte_zmalloc(%d"
1233 " (struct fwd_stream *)) failed\n",
1236 for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) {
1237 fwd_streams[sm_id] = rte_zmalloc("testpmd:"
1238 " struct fwd_stream", sizeof(struct fwd_stream),
1239 RTE_CACHE_LINE_SIZE);
1240 if (fwd_streams[sm_id] == NULL)
1241 rte_exit(EXIT_FAILURE, "rte_zmalloc"
1242 "(struct fwd_stream) failed\n");
1249 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1251 pkt_burst_stats_display(const char *rx_tx, struct pkt_burst_stats *pbs)
1253 unsigned int total_burst;
1254 unsigned int nb_burst;
1255 unsigned int burst_stats[3];
1256 uint16_t pktnb_stats[3];
1258 int burst_percent[3];
1261 * First compute the total number of packet bursts and the
1262 * two highest numbers of bursts of the same number of packets.
1265 burst_stats[0] = burst_stats[1] = burst_stats[2] = 0;
1266 pktnb_stats[0] = pktnb_stats[1] = pktnb_stats[2] = 0;
1267 for (nb_pkt = 0; nb_pkt < MAX_PKT_BURST; nb_pkt++) {
1268 nb_burst = pbs->pkt_burst_spread[nb_pkt];
1271 total_burst += nb_burst;
1272 if (nb_burst > burst_stats[0]) {
1273 burst_stats[1] = burst_stats[0];
1274 pktnb_stats[1] = pktnb_stats[0];
1275 burst_stats[0] = nb_burst;
1276 pktnb_stats[0] = nb_pkt;
1277 } else if (nb_burst > burst_stats[1]) {
1278 burst_stats[1] = nb_burst;
1279 pktnb_stats[1] = nb_pkt;
1282 if (total_burst == 0)
1284 burst_percent[0] = (burst_stats[0] * 100) / total_burst;
1285 printf(" %s-bursts : %u [%d%% of %d pkts", rx_tx, total_burst,
1286 burst_percent[0], (int) pktnb_stats[0]);
1287 if (burst_stats[0] == total_burst) {
1291 if (burst_stats[0] + burst_stats[1] == total_burst) {
1292 printf(" + %d%% of %d pkts]\n",
1293 100 - burst_percent[0], pktnb_stats[1]);
1296 burst_percent[1] = (burst_stats[1] * 100) / total_burst;
1297 burst_percent[2] = 100 - (burst_percent[0] + burst_percent[1]);
1298 if ((burst_percent[1] == 0) || (burst_percent[2] == 0)) {
1299 printf(" + %d%% of others]\n", 100 - burst_percent[0]);
1302 printf(" + %d%% of %d pkts + %d%% of others]\n",
1303 burst_percent[1], (int) pktnb_stats[1], burst_percent[2]);
1305 #endif /* RTE_TEST_PMD_RECORD_BURST_STATS */
1308 fwd_port_stats_display(portid_t port_id, struct rte_eth_stats *stats)
1310 struct rte_port *port;
1313 static const char *fwd_stats_border = "----------------------";
1315 port = &ports[port_id];
1316 printf("\n %s Forward statistics for port %-2d %s\n",
1317 fwd_stats_border, port_id, fwd_stats_border);
1319 if ((!port->rx_queue_stats_mapping_enabled) && (!port->tx_queue_stats_mapping_enabled)) {
1320 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1322 stats->ipackets, stats->imissed,
1323 (uint64_t) (stats->ipackets + stats->imissed));
1325 if (cur_fwd_eng == &csum_fwd_engine)
1326 printf(" Bad-ipcsum: %-14"PRIu64" Bad-l4csum: %-14"PRIu64"Bad-outer-l4csum: %-14"PRIu64"\n",
1327 port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1328 port->rx_bad_outer_l4_csum);
1329 if ((stats->ierrors + stats->rx_nombuf) > 0) {
1330 printf(" RX-error: %-"PRIu64"\n", stats->ierrors);
1331 printf(" RX-nombufs: %-14"PRIu64"\n", stats->rx_nombuf);
1334 printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1336 stats->opackets, port->tx_dropped,
1337 (uint64_t) (stats->opackets + port->tx_dropped));
1340 printf(" RX-packets: %14"PRIu64" RX-dropped:%14"PRIu64" RX-total:"
1342 stats->ipackets, stats->imissed,
1343 (uint64_t) (stats->ipackets + stats->imissed));
1345 if (cur_fwd_eng == &csum_fwd_engine)
1346 printf(" Bad-ipcsum:%14"PRIu64" Bad-l4csum:%14"PRIu64" Bad-outer-l4csum: %-14"PRIu64"\n",
1347 port->rx_bad_ip_csum, port->rx_bad_l4_csum,
1348 port->rx_bad_outer_l4_csum);
1349 if ((stats->ierrors + stats->rx_nombuf) > 0) {
1350 printf(" RX-error:%"PRIu64"\n", stats->ierrors);
1351 printf(" RX-nombufs: %14"PRIu64"\n",
1355 printf(" TX-packets: %14"PRIu64" TX-dropped:%14"PRIu64" TX-total:"
1357 stats->opackets, port->tx_dropped,
1358 (uint64_t) (stats->opackets + port->tx_dropped));
1361 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1362 if (port->rx_stream)
1363 pkt_burst_stats_display("RX",
1364 &port->rx_stream->rx_burst_stats);
1365 if (port->tx_stream)
1366 pkt_burst_stats_display("TX",
1367 &port->tx_stream->tx_burst_stats);
1370 if (port->rx_queue_stats_mapping_enabled) {
1372 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1373 printf(" Stats reg %2d RX-packets:%14"PRIu64
1374 " RX-errors:%14"PRIu64
1375 " RX-bytes:%14"PRIu64"\n",
1376 i, stats->q_ipackets[i], stats->q_errors[i], stats->q_ibytes[i]);
1380 if (port->tx_queue_stats_mapping_enabled) {
1381 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
1382 printf(" Stats reg %2d TX-packets:%14"PRIu64
1383 " TX-bytes:%14"PRIu64"\n",
1384 i, stats->q_opackets[i], stats->q_obytes[i]);
1388 printf(" %s--------------------------------%s\n",
1389 fwd_stats_border, fwd_stats_border);
1393 fwd_stream_stats_display(streamid_t stream_id)
1395 struct fwd_stream *fs;
1396 static const char *fwd_top_stats_border = "-------";
1398 fs = fwd_streams[stream_id];
1399 if ((fs->rx_packets == 0) && (fs->tx_packets == 0) &&
1400 (fs->fwd_dropped == 0))
1402 printf("\n %s Forward Stats for RX Port=%2d/Queue=%2d -> "
1403 "TX Port=%2d/Queue=%2d %s\n",
1404 fwd_top_stats_border, fs->rx_port, fs->rx_queue,
1405 fs->tx_port, fs->tx_queue, fwd_top_stats_border);
1406 printf(" RX-packets: %-14u TX-packets: %-14u TX-dropped: %-14u",
1407 fs->rx_packets, fs->tx_packets, fs->fwd_dropped);
1409 /* if checksum mode */
1410 if (cur_fwd_eng == &csum_fwd_engine) {
1411 printf(" RX- bad IP checksum: %-14u Rx- bad L4 checksum: "
1412 "%-14u Rx- bad outer L4 checksum: %-14u\n",
1413 fs->rx_bad_ip_csum, fs->rx_bad_l4_csum,
1414 fs->rx_bad_outer_l4_csum);
1417 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1418 pkt_burst_stats_display("RX", &fs->rx_burst_stats);
1419 pkt_burst_stats_display("TX", &fs->tx_burst_stats);
1424 flush_fwd_rx_queues(void)
1426 struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
1433 uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
1434 uint64_t timer_period;
1436 /* convert to number of cycles */
1437 timer_period = rte_get_timer_hz(); /* 1 second timeout */
1439 for (j = 0; j < 2; j++) {
1440 for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) {
1441 for (rxq = 0; rxq < nb_rxq; rxq++) {
1442 port_id = fwd_ports_ids[rxp];
1444 * testpmd can stuck in the below do while loop
1445 * if rte_eth_rx_burst() always returns nonzero
1446 * packets. So timer is added to exit this loop
1447 * after 1sec timer expiry.
1449 prev_tsc = rte_rdtsc();
1451 nb_rx = rte_eth_rx_burst(port_id, rxq,
1452 pkts_burst, MAX_PKT_BURST);
1453 for (i = 0; i < nb_rx; i++)
1454 rte_pktmbuf_free(pkts_burst[i]);
1456 cur_tsc = rte_rdtsc();
1457 diff_tsc = cur_tsc - prev_tsc;
1458 timer_tsc += diff_tsc;
1459 } while ((nb_rx > 0) &&
1460 (timer_tsc < timer_period));
1464 rte_delay_ms(10); /* wait 10 milli-seconds before retrying */
1469 run_pkt_fwd_on_lcore(struct fwd_lcore *fc, packet_fwd_t pkt_fwd)
1471 struct fwd_stream **fsm;
1474 #ifdef RTE_LIBRTE_BITRATE
1475 uint64_t tics_per_1sec;
1476 uint64_t tics_datum;
1477 uint64_t tics_current;
1478 uint16_t i, cnt_ports;
1480 cnt_ports = nb_ports;
1481 tics_datum = rte_rdtsc();
1482 tics_per_1sec = rte_get_timer_hz();
1484 fsm = &fwd_streams[fc->stream_idx];
1485 nb_fs = fc->stream_nb;
1487 for (sm_id = 0; sm_id < nb_fs; sm_id++)
1488 (*pkt_fwd)(fsm[sm_id]);
1489 #ifdef RTE_LIBRTE_BITRATE
1490 if (bitrate_enabled != 0 &&
1491 bitrate_lcore_id == rte_lcore_id()) {
1492 tics_current = rte_rdtsc();
1493 if (tics_current - tics_datum >= tics_per_1sec) {
1494 /* Periodic bitrate calculation */
1495 for (i = 0; i < cnt_ports; i++)
1496 rte_stats_bitrate_calc(bitrate_data,
1498 tics_datum = tics_current;
1502 #ifdef RTE_LIBRTE_LATENCY_STATS
1503 if (latencystats_enabled != 0 &&
1504 latencystats_lcore_id == rte_lcore_id())
1505 rte_latencystats_update();
1508 } while (! fc->stopped);
1512 start_pkt_forward_on_core(void *fwd_arg)
1514 run_pkt_fwd_on_lcore((struct fwd_lcore *) fwd_arg,
1515 cur_fwd_config.fwd_eng->packet_fwd);
1520 * Run the TXONLY packet forwarding engine to send a single burst of packets.
1521 * Used to start communication flows in network loopback test configurations.
1524 run_one_txonly_burst_on_core(void *fwd_arg)
1526 struct fwd_lcore *fwd_lc;
1527 struct fwd_lcore tmp_lcore;
1529 fwd_lc = (struct fwd_lcore *) fwd_arg;
1530 tmp_lcore = *fwd_lc;
1531 tmp_lcore.stopped = 1;
1532 run_pkt_fwd_on_lcore(&tmp_lcore, tx_only_engine.packet_fwd);
1537 * Launch packet forwarding:
1538 * - Setup per-port forwarding context.
1539 * - launch logical cores with their forwarding configuration.
1542 launch_packet_forwarding(lcore_function_t *pkt_fwd_on_lcore)
1544 port_fwd_begin_t port_fwd_begin;
1549 port_fwd_begin = cur_fwd_config.fwd_eng->port_fwd_begin;
1550 if (port_fwd_begin != NULL) {
1551 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1552 (*port_fwd_begin)(fwd_ports_ids[i]);
1554 for (i = 0; i < cur_fwd_config.nb_fwd_lcores; i++) {
1555 lc_id = fwd_lcores_cpuids[i];
1556 if ((interactive == 0) || (lc_id != rte_lcore_id())) {
1557 fwd_lcores[i]->stopped = 0;
1558 diag = rte_eal_remote_launch(pkt_fwd_on_lcore,
1559 fwd_lcores[i], lc_id);
1561 printf("launch lcore %u failed - diag=%d\n",
1568 * Update the forward ports list.
1571 update_fwd_ports(portid_t new_pid)
1574 unsigned int new_nb_fwd_ports = 0;
1577 for (i = 0; i < nb_fwd_ports; ++i) {
1578 if (port_id_is_invalid(fwd_ports_ids[i], DISABLED_WARN))
1581 fwd_ports_ids[new_nb_fwd_ports++] = fwd_ports_ids[i];
1585 if (new_pid < RTE_MAX_ETHPORTS)
1586 fwd_ports_ids[new_nb_fwd_ports++] = new_pid;
1588 nb_fwd_ports = new_nb_fwd_ports;
1589 nb_cfg_ports = new_nb_fwd_ports;
1593 * Launch packet forwarding configuration.
1596 start_packet_forwarding(int with_tx_first)
1598 port_fwd_begin_t port_fwd_begin;
1599 port_fwd_end_t port_fwd_end;
1600 struct rte_port *port;
1605 if (strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") == 0 && !nb_rxq)
1606 rte_exit(EXIT_FAILURE, "rxq are 0, cannot use rxonly fwd mode\n");
1608 if (strcmp(cur_fwd_eng->fwd_mode_name, "txonly") == 0 && !nb_txq)
1609 rte_exit(EXIT_FAILURE, "txq are 0, cannot use txonly fwd mode\n");
1611 if ((strcmp(cur_fwd_eng->fwd_mode_name, "rxonly") != 0 &&
1612 strcmp(cur_fwd_eng->fwd_mode_name, "txonly") != 0) &&
1613 (!nb_rxq || !nb_txq))
1614 rte_exit(EXIT_FAILURE,
1615 "Either rxq or txq are 0, cannot use %s fwd mode\n",
1616 cur_fwd_eng->fwd_mode_name);
1618 if (all_ports_started() == 0) {
1619 printf("Not all ports were started\n");
1622 if (test_done == 0) {
1623 printf("Packet forwarding already started\n");
1629 for (i = 0; i < nb_fwd_ports; i++) {
1630 pt_id = fwd_ports_ids[i];
1631 port = &ports[pt_id];
1632 if (!port->dcb_flag) {
1633 printf("In DCB mode, all forwarding ports must "
1634 "be configured in this mode.\n");
1638 if (nb_fwd_lcores == 1) {
1639 printf("In DCB mode,the nb forwarding cores "
1640 "should be larger than 1.\n");
1649 flush_fwd_rx_queues();
1651 pkt_fwd_config_display(&cur_fwd_config);
1652 rxtx_config_display();
1654 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1655 pt_id = fwd_ports_ids[i];
1656 port = &ports[pt_id];
1657 rte_eth_stats_get(pt_id, &port->stats);
1658 port->tx_dropped = 0;
1660 map_port_queue_stats_mapping_registers(pt_id, port);
1662 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1663 fwd_streams[sm_id]->rx_packets = 0;
1664 fwd_streams[sm_id]->tx_packets = 0;
1665 fwd_streams[sm_id]->fwd_dropped = 0;
1666 fwd_streams[sm_id]->rx_bad_ip_csum = 0;
1667 fwd_streams[sm_id]->rx_bad_l4_csum = 0;
1668 fwd_streams[sm_id]->rx_bad_outer_l4_csum = 0;
1670 #ifdef RTE_TEST_PMD_RECORD_BURST_STATS
1671 memset(&fwd_streams[sm_id]->rx_burst_stats, 0,
1672 sizeof(fwd_streams[sm_id]->rx_burst_stats));
1673 memset(&fwd_streams[sm_id]->tx_burst_stats, 0,
1674 sizeof(fwd_streams[sm_id]->tx_burst_stats));
1676 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1677 fwd_streams[sm_id]->core_cycles = 0;
1680 if (with_tx_first) {
1681 port_fwd_begin = tx_only_engine.port_fwd_begin;
1682 if (port_fwd_begin != NULL) {
1683 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1684 (*port_fwd_begin)(fwd_ports_ids[i]);
1686 while (with_tx_first--) {
1687 launch_packet_forwarding(
1688 run_one_txonly_burst_on_core);
1689 rte_eal_mp_wait_lcore();
1691 port_fwd_end = tx_only_engine.port_fwd_end;
1692 if (port_fwd_end != NULL) {
1693 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
1694 (*port_fwd_end)(fwd_ports_ids[i]);
1697 launch_packet_forwarding(start_pkt_forward_on_core);
1701 stop_packet_forwarding(void)
1703 struct rte_eth_stats stats;
1704 struct rte_port *port;
1705 port_fwd_end_t port_fwd_end;
1710 uint64_t total_recv;
1711 uint64_t total_xmit;
1712 uint64_t total_rx_dropped;
1713 uint64_t total_tx_dropped;
1714 uint64_t total_rx_nombuf;
1715 uint64_t tx_dropped;
1716 uint64_t rx_bad_ip_csum;
1717 uint64_t rx_bad_l4_csum;
1718 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1719 uint64_t fwd_cycles;
1722 static const char *acc_stats_border = "+++++++++++++++";
1725 printf("Packet forwarding not started\n");
1728 printf("Telling cores to stop...");
1729 for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++)
1730 fwd_lcores[lc_id]->stopped = 1;
1731 printf("\nWaiting for lcores to finish...\n");
1732 rte_eal_mp_wait_lcore();
1733 port_fwd_end = cur_fwd_config.fwd_eng->port_fwd_end;
1734 if (port_fwd_end != NULL) {
1735 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1736 pt_id = fwd_ports_ids[i];
1737 (*port_fwd_end)(pt_id);
1740 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1743 for (sm_id = 0; sm_id < cur_fwd_config.nb_fwd_streams; sm_id++) {
1744 if (cur_fwd_config.nb_fwd_streams >
1745 cur_fwd_config.nb_fwd_ports) {
1746 fwd_stream_stats_display(sm_id);
1747 ports[fwd_streams[sm_id]->tx_port].tx_stream = NULL;
1748 ports[fwd_streams[sm_id]->rx_port].rx_stream = NULL;
1750 ports[fwd_streams[sm_id]->tx_port].tx_stream =
1752 ports[fwd_streams[sm_id]->rx_port].rx_stream =
1755 tx_dropped = ports[fwd_streams[sm_id]->tx_port].tx_dropped;
1756 tx_dropped = (uint64_t) (tx_dropped +
1757 fwd_streams[sm_id]->fwd_dropped);
1758 ports[fwd_streams[sm_id]->tx_port].tx_dropped = tx_dropped;
1761 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum;
1762 rx_bad_ip_csum = (uint64_t) (rx_bad_ip_csum +
1763 fwd_streams[sm_id]->rx_bad_ip_csum);
1764 ports[fwd_streams[sm_id]->rx_port].rx_bad_ip_csum =
1768 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum;
1769 rx_bad_l4_csum = (uint64_t) (rx_bad_l4_csum +
1770 fwd_streams[sm_id]->rx_bad_l4_csum);
1771 ports[fwd_streams[sm_id]->rx_port].rx_bad_l4_csum =
1774 ports[fwd_streams[sm_id]->rx_port].rx_bad_outer_l4_csum +=
1775 fwd_streams[sm_id]->rx_bad_outer_l4_csum;
1777 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1778 fwd_cycles = (uint64_t) (fwd_cycles +
1779 fwd_streams[sm_id]->core_cycles);
1784 total_rx_dropped = 0;
1785 total_tx_dropped = 0;
1786 total_rx_nombuf = 0;
1787 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) {
1788 pt_id = fwd_ports_ids[i];
1790 port = &ports[pt_id];
1791 rte_eth_stats_get(pt_id, &stats);
1792 stats.ipackets -= port->stats.ipackets;
1793 port->stats.ipackets = 0;
1794 stats.opackets -= port->stats.opackets;
1795 port->stats.opackets = 0;
1796 stats.ibytes -= port->stats.ibytes;
1797 port->stats.ibytes = 0;
1798 stats.obytes -= port->stats.obytes;
1799 port->stats.obytes = 0;
1800 stats.imissed -= port->stats.imissed;
1801 port->stats.imissed = 0;
1802 stats.oerrors -= port->stats.oerrors;
1803 port->stats.oerrors = 0;
1804 stats.rx_nombuf -= port->stats.rx_nombuf;
1805 port->stats.rx_nombuf = 0;
1807 total_recv += stats.ipackets;
1808 total_xmit += stats.opackets;
1809 total_rx_dropped += stats.imissed;
1810 total_tx_dropped += port->tx_dropped;
1811 total_rx_nombuf += stats.rx_nombuf;
1813 fwd_port_stats_display(pt_id, &stats);
1816 printf("\n %s Accumulated forward statistics for all ports"
1818 acc_stats_border, acc_stats_border);
1819 printf(" RX-packets: %-14"PRIu64" RX-dropped: %-14"PRIu64"RX-total: "
1821 " TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64"TX-total: "
1823 total_recv, total_rx_dropped, total_recv + total_rx_dropped,
1824 total_xmit, total_tx_dropped, total_xmit + total_tx_dropped);
1825 if (total_rx_nombuf > 0)
1826 printf(" RX-nombufs: %-14"PRIu64"\n", total_rx_nombuf);
1827 printf(" %s++++++++++++++++++++++++++++++++++++++++++++++"
1829 acc_stats_border, acc_stats_border);
1830 #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
1832 printf("\n CPU cycles/packet=%u (total cycles="
1833 "%"PRIu64" / total RX packets=%"PRIu64")\n",
1834 (unsigned int)(fwd_cycles / total_recv),
1835 fwd_cycles, total_recv);
1837 printf("\nDone.\n");
1842 dev_set_link_up(portid_t pid)
1844 if (rte_eth_dev_set_link_up(pid) < 0)
1845 printf("\nSet link up fail.\n");
1849 dev_set_link_down(portid_t pid)
1851 if (rte_eth_dev_set_link_down(pid) < 0)
1852 printf("\nSet link down fail.\n");
1856 all_ports_started(void)
1859 struct rte_port *port;
1861 RTE_ETH_FOREACH_DEV(pi) {
1863 /* Check if there is a port which is not started */
1864 if ((port->port_status != RTE_PORT_STARTED) &&
1865 (port->slave_flag == 0))
1869 /* No port is not started */
1874 port_is_stopped(portid_t port_id)
1876 struct rte_port *port = &ports[port_id];
1878 if ((port->port_status != RTE_PORT_STOPPED) &&
1879 (port->slave_flag == 0))
1885 all_ports_stopped(void)
1889 RTE_ETH_FOREACH_DEV(pi) {
1890 if (!port_is_stopped(pi))
1898 port_is_started(portid_t port_id)
1900 if (port_id_is_invalid(port_id, ENABLED_WARN))
1903 if (ports[port_id].port_status != RTE_PORT_STARTED)
1910 port_is_closed(portid_t port_id)
1912 if (port_id_is_invalid(port_id, ENABLED_WARN))
1915 if (ports[port_id].port_status != RTE_PORT_CLOSED)
1922 start_port(portid_t pid)
1924 int diag, need_check_link_status = -1;
1927 struct rte_port *port;
1928 struct ether_addr mac_addr;
1929 enum rte_eth_event_type event_type;
1931 if (port_id_is_invalid(pid, ENABLED_WARN))
1936 RTE_ETH_FOREACH_DEV(pi) {
1937 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
1940 need_check_link_status = 0;
1942 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED,
1943 RTE_PORT_HANDLING) == 0) {
1944 printf("Port %d is now not stopped\n", pi);
1948 if (port->need_reconfig > 0) {
1949 port->need_reconfig = 0;
1951 if (flow_isolate_all) {
1952 int ret = port_flow_isolate(pi, 1);
1954 printf("Failed to apply isolated"
1955 " mode on port %d\n", pi);
1960 printf("Configuring Port %d (socket %u)\n", pi,
1962 /* configure port */
1963 diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq,
1966 if (rte_atomic16_cmpset(&(port->port_status),
1967 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
1968 printf("Port %d can not be set back "
1969 "to stopped\n", pi);
1970 printf("Fail to configure port %d\n", pi);
1971 /* try to reconfigure port next time */
1972 port->need_reconfig = 1;
1976 if (port->need_reconfig_queues > 0) {
1977 port->need_reconfig_queues = 0;
1978 /* setup tx queues */
1979 for (qi = 0; qi < nb_txq; qi++) {
1980 if ((numa_support) &&
1981 (txring_numa[pi] != NUMA_NO_CONFIG))
1982 diag = rte_eth_tx_queue_setup(pi, qi,
1983 port->nb_tx_desc[qi],
1985 &(port->tx_conf[qi]));
1987 diag = rte_eth_tx_queue_setup(pi, qi,
1988 port->nb_tx_desc[qi],
1990 &(port->tx_conf[qi]));
1995 /* Fail to setup tx queue, return */
1996 if (rte_atomic16_cmpset(&(port->port_status),
1998 RTE_PORT_STOPPED) == 0)
1999 printf("Port %d can not be set back "
2000 "to stopped\n", pi);
2001 printf("Fail to configure port %d tx queues\n",
2003 /* try to reconfigure queues next time */
2004 port->need_reconfig_queues = 1;
2007 for (qi = 0; qi < nb_rxq; qi++) {
2008 /* setup rx queues */
2009 if ((numa_support) &&
2010 (rxring_numa[pi] != NUMA_NO_CONFIG)) {
2011 struct rte_mempool * mp =
2012 mbuf_pool_find(rxring_numa[pi]);
2014 printf("Failed to setup RX queue:"
2015 "No mempool allocation"
2016 " on the socket %d\n",
2021 diag = rte_eth_rx_queue_setup(pi, qi,
2022 port->nb_rx_desc[qi],
2024 &(port->rx_conf[qi]),
2027 struct rte_mempool *mp =
2028 mbuf_pool_find(port->socket_id);
2030 printf("Failed to setup RX queue:"
2031 "No mempool allocation"
2032 " on the socket %d\n",
2036 diag = rte_eth_rx_queue_setup(pi, qi,
2037 port->nb_rx_desc[qi],
2039 &(port->rx_conf[qi]),
2045 /* Fail to setup rx queue, return */
2046 if (rte_atomic16_cmpset(&(port->port_status),
2048 RTE_PORT_STOPPED) == 0)
2049 printf("Port %d can not be set back "
2050 "to stopped\n", pi);
2051 printf("Fail to configure port %d rx queues\n",
2053 /* try to reconfigure queues next time */
2054 port->need_reconfig_queues = 1;
2060 if (rte_eth_dev_start(pi) < 0) {
2061 printf("Fail to start port %d\n", pi);
2063 /* Fail to setup rx queue, return */
2064 if (rte_atomic16_cmpset(&(port->port_status),
2065 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2066 printf("Port %d can not be set back to "
2071 if (rte_atomic16_cmpset(&(port->port_status),
2072 RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0)
2073 printf("Port %d can not be set into started\n", pi);
2075 rte_eth_macaddr_get(pi, &mac_addr);
2076 printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi,
2077 mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
2078 mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
2079 mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]);
2081 /* at least one port started, need checking link status */
2082 need_check_link_status = 1;
2085 for (event_type = RTE_ETH_EVENT_UNKNOWN;
2086 event_type < RTE_ETH_EVENT_MAX;
2088 diag = rte_eth_dev_callback_register(RTE_ETH_ALL,
2093 printf("Failed to setup even callback for event %d\n",
2099 if (need_check_link_status == 1 && !no_link_check)
2100 check_all_ports_link_status(RTE_PORT_ALL);
2101 else if (need_check_link_status == 0)
2102 printf("Please stop the ports first\n");
2109 stop_port(portid_t pid)
2112 struct rte_port *port;
2113 int need_check_link_status = 0;
2120 if (port_id_is_invalid(pid, ENABLED_WARN))
2123 printf("Stopping ports...\n");
2125 RTE_ETH_FOREACH_DEV(pi) {
2126 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2129 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2130 printf("Please remove port %d from forwarding configuration.\n", pi);
2134 if (port_is_bonding_slave(pi)) {
2135 printf("Please remove port %d from bonded device.\n", pi);
2140 if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED,
2141 RTE_PORT_HANDLING) == 0)
2144 rte_eth_dev_stop(pi);
2146 if (rte_atomic16_cmpset(&(port->port_status),
2147 RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0)
2148 printf("Port %d can not be set into stopped\n", pi);
2149 need_check_link_status = 1;
2151 if (need_check_link_status && !no_link_check)
2152 check_all_ports_link_status(RTE_PORT_ALL);
2158 close_port(portid_t pid)
2161 struct rte_port *port;
2163 if (port_id_is_invalid(pid, ENABLED_WARN))
2166 printf("Closing ports...\n");
2168 RTE_ETH_FOREACH_DEV(pi) {
2169 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2172 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2173 printf("Please remove port %d from forwarding configuration.\n", pi);
2177 if (port_is_bonding_slave(pi)) {
2178 printf("Please remove port %d from bonded device.\n", pi);
2183 if (rte_atomic16_cmpset(&(port->port_status),
2184 RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) {
2185 printf("Port %d is already closed\n", pi);
2189 if (rte_atomic16_cmpset(&(port->port_status),
2190 RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) {
2191 printf("Port %d is now not stopped\n", pi);
2195 if (port->flow_list)
2196 port_flow_flush(pi);
2197 rte_eth_dev_close(pi);
2199 if (rte_atomic16_cmpset(&(port->port_status),
2200 RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0)
2201 printf("Port %d cannot be set to closed\n", pi);
2208 reset_port(portid_t pid)
2212 struct rte_port *port;
2214 if (port_id_is_invalid(pid, ENABLED_WARN))
2217 printf("Resetting ports...\n");
2219 RTE_ETH_FOREACH_DEV(pi) {
2220 if (pid != pi && pid != (portid_t)RTE_PORT_ALL)
2223 if (port_is_forwarding(pi) != 0 && test_done == 0) {
2224 printf("Please remove port %d from forwarding "
2225 "configuration.\n", pi);
2229 if (port_is_bonding_slave(pi)) {
2230 printf("Please remove port %d from bonded device.\n",
2235 diag = rte_eth_dev_reset(pi);
2238 port->need_reconfig = 1;
2239 port->need_reconfig_queues = 1;
2241 printf("Failed to reset port %d. diag=%d\n", pi, diag);
2249 eth_dev_event_callback_register(void)
2253 /* register the device event callback */
2254 ret = rte_dev_event_callback_register(NULL,
2255 eth_dev_event_callback, NULL);
2257 printf("Failed to register device event callback\n");
2266 eth_dev_event_callback_unregister(void)
2270 /* unregister the device event callback */
2271 ret = rte_dev_event_callback_unregister(NULL,
2272 eth_dev_event_callback, NULL);
2274 printf("Failed to unregister device event callback\n");
2282 attach_port(char *identifier)
2285 unsigned int socket_id;
2287 printf("Attaching a new port...\n");
2289 if (identifier == NULL) {
2290 printf("Invalid parameters are specified\n");
2294 if (rte_eth_dev_attach(identifier, &pi))
2297 socket_id = (unsigned)rte_eth_dev_socket_id(pi);
2298 /* if socket_id is invalid, set to 0 */
2299 if (check_socket_id(socket_id) < 0)
2301 reconfig(pi, socket_id);
2302 rte_eth_promiscuous_enable(pi);
2304 ports_ids[nb_ports] = pi;
2305 nb_ports = rte_eth_dev_count_avail();
2307 ports[pi].port_status = RTE_PORT_STOPPED;
2309 update_fwd_ports(pi);
2311 printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
2316 detach_port(portid_t port_id)
2318 char name[RTE_ETH_NAME_MAX_LEN];
2321 printf("Detaching a port...\n");
2323 if (!port_is_closed(port_id)) {
2324 printf("Please close port first\n");
2328 if (ports[port_id].flow_list)
2329 port_flow_flush(port_id);
2331 if (rte_eth_dev_detach(port_id, name)) {
2332 TESTPMD_LOG(ERR, "Failed to detach port %u\n", port_id);
2336 for (i = 0; i < nb_ports; i++) {
2337 if (ports_ids[i] == port_id) {
2338 ports_ids[i] = ports_ids[nb_ports-1];
2339 ports_ids[nb_ports-1] = 0;
2343 nb_ports = rte_eth_dev_count_avail();
2345 update_fwd_ports(RTE_MAX_ETHPORTS);
2347 printf("Port %u is detached. Now total ports is %d\n",
2356 struct rte_device *device;
2361 stop_packet_forwarding();
2363 if (ports != NULL) {
2365 RTE_ETH_FOREACH_DEV(pt_id) {
2366 printf("\nShutting down port %d...\n", pt_id);
2372 * This is a workaround to fix a virtio-user issue that
2373 * requires to call clean-up routine to remove existing
2375 * This workaround valid only for testpmd, needs a fix
2376 * valid for all applications.
2377 * TODO: Implement proper resource cleanup
2379 device = rte_eth_devices[pt_id].device;
2380 if (device && !strcmp(device->driver->name, "net_virtio_user"))
2386 ret = rte_dev_event_monitor_stop();
2389 "fail to stop device event monitor.");
2391 ret = eth_dev_event_callback_unregister();
2394 "fail to unregister all event callbacks.");
2397 printf("\nBye...\n");
2400 typedef void (*cmd_func_t)(void);
2401 struct pmd_test_command {
2402 const char *cmd_name;
2403 cmd_func_t cmd_func;
2406 #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0]))
2408 /* Check the link status of all ports in up to 9s, and print them finally */
2410 check_all_ports_link_status(uint32_t port_mask)
2412 #define CHECK_INTERVAL 100 /* 100ms */
2413 #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2415 uint8_t count, all_ports_up, print_flag = 0;
2416 struct rte_eth_link link;
2418 printf("Checking link statuses...\n");
2420 for (count = 0; count <= MAX_CHECK_TIME; count++) {
2422 RTE_ETH_FOREACH_DEV(portid) {
2423 if ((port_mask & (1 << portid)) == 0)
2425 memset(&link, 0, sizeof(link));
2426 rte_eth_link_get_nowait(portid, &link);
2427 /* print link status if flag set */
2428 if (print_flag == 1) {
2429 if (link.link_status)
2431 "Port%d Link Up. speed %u Mbps- %s\n",
2432 portid, link.link_speed,
2433 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
2434 ("full-duplex") : ("half-duplex\n"));
2436 printf("Port %d Link Down\n", portid);
2439 /* clear all_ports_up flag if any link down */
2440 if (link.link_status == ETH_LINK_DOWN) {
2445 /* after finally printing all link status, get out */
2446 if (print_flag == 1)
2449 if (all_ports_up == 0) {
2451 rte_delay_ms(CHECK_INTERVAL);
2454 /* set the print_flag if all ports up or timeout */
2455 if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2465 rmv_event_callback(void *arg)
2467 int need_to_start = 0;
2468 int org_no_link_check = no_link_check;
2469 portid_t port_id = (intptr_t)arg;
2471 RTE_ETH_VALID_PORTID_OR_RET(port_id);
2473 if (!test_done && port_is_forwarding(port_id)) {
2475 stop_packet_forwarding();
2479 no_link_check = org_no_link_check;
2480 close_port(port_id);
2481 detach_port(port_id);
2483 start_packet_forwarding(0);
2486 /* This function is used by the interrupt thread */
2488 eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
2491 static const char * const event_desc[] = {
2492 [RTE_ETH_EVENT_UNKNOWN] = "Unknown",
2493 [RTE_ETH_EVENT_INTR_LSC] = "LSC",
2494 [RTE_ETH_EVENT_QUEUE_STATE] = "Queue state",
2495 [RTE_ETH_EVENT_INTR_RESET] = "Interrupt reset",
2496 [RTE_ETH_EVENT_VF_MBOX] = "VF Mbox",
2497 [RTE_ETH_EVENT_IPSEC] = "IPsec",
2498 [RTE_ETH_EVENT_MACSEC] = "MACsec",
2499 [RTE_ETH_EVENT_INTR_RMV] = "device removal",
2500 [RTE_ETH_EVENT_NEW] = "device probed",
2501 [RTE_ETH_EVENT_DESTROY] = "device released",
2502 [RTE_ETH_EVENT_MAX] = NULL,
2505 RTE_SET_USED(param);
2506 RTE_SET_USED(ret_param);
2508 if (type >= RTE_ETH_EVENT_MAX) {
2509 fprintf(stderr, "\nPort %" PRIu16 ": %s called upon invalid event %d\n",
2510 port_id, __func__, type);
2512 } else if (event_print_mask & (UINT32_C(1) << type)) {
2513 printf("\nPort %" PRIu16 ": %s event\n", port_id,
2518 if (port_id_is_invalid(port_id, DISABLED_WARN))
2522 case RTE_ETH_EVENT_INTR_RMV:
2523 if (rte_eal_alarm_set(100000,
2524 rmv_event_callback, (void *)(intptr_t)port_id))
2525 fprintf(stderr, "Could not set up deferred device removal\n");
2533 /* This function is used by the interrupt thread */
2535 eth_dev_event_callback(char *device_name, enum rte_dev_event_type type,
2536 __rte_unused void *arg)
2538 if (type >= RTE_DEV_EVENT_MAX) {
2539 fprintf(stderr, "%s called upon invalid event %d\n",
2545 case RTE_DEV_EVENT_REMOVE:
2546 RTE_LOG(ERR, EAL, "The device: %s has been removed!\n",
2548 /* TODO: After finish failure handle, begin to stop
2549 * packet forward, stop port, close port, detach port.
2552 case RTE_DEV_EVENT_ADD:
2553 RTE_LOG(ERR, EAL, "The device: %s has been added!\n",
2555 /* TODO: After finish kernel driver binding,
2556 * begin to attach port.
2565 set_tx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2569 uint8_t mapping_found = 0;
2571 for (i = 0; i < nb_tx_queue_stats_mappings; i++) {
2572 if ((tx_queue_stats_mappings[i].port_id == port_id) &&
2573 (tx_queue_stats_mappings[i].queue_id < nb_txq )) {
2574 diag = rte_eth_dev_set_tx_queue_stats_mapping(port_id,
2575 tx_queue_stats_mappings[i].queue_id,
2576 tx_queue_stats_mappings[i].stats_counter_id);
2583 port->tx_queue_stats_mapping_enabled = 1;
2588 set_rx_queue_stats_mapping_registers(portid_t port_id, struct rte_port *port)
2592 uint8_t mapping_found = 0;
2594 for (i = 0; i < nb_rx_queue_stats_mappings; i++) {
2595 if ((rx_queue_stats_mappings[i].port_id == port_id) &&
2596 (rx_queue_stats_mappings[i].queue_id < nb_rxq )) {
2597 diag = rte_eth_dev_set_rx_queue_stats_mapping(port_id,
2598 rx_queue_stats_mappings[i].queue_id,
2599 rx_queue_stats_mappings[i].stats_counter_id);
2606 port->rx_queue_stats_mapping_enabled = 1;
2611 map_port_queue_stats_mapping_registers(portid_t pi, struct rte_port *port)
2615 diag = set_tx_queue_stats_mapping_registers(pi, port);
2617 if (diag == -ENOTSUP) {
2618 port->tx_queue_stats_mapping_enabled = 0;
2619 printf("TX queue stats mapping not supported port id=%d\n", pi);
2622 rte_exit(EXIT_FAILURE,
2623 "set_tx_queue_stats_mapping_registers "
2624 "failed for port id=%d diag=%d\n",
2628 diag = set_rx_queue_stats_mapping_registers(pi, port);
2630 if (diag == -ENOTSUP) {
2631 port->rx_queue_stats_mapping_enabled = 0;
2632 printf("RX queue stats mapping not supported port id=%d\n", pi);
2635 rte_exit(EXIT_FAILURE,
2636 "set_rx_queue_stats_mapping_registers "
2637 "failed for port id=%d diag=%d\n",
2643 rxtx_port_config(struct rte_port *port)
2647 for (qid = 0; qid < nb_rxq; qid++) {
2648 port->rx_conf[qid] = port->dev_info.default_rxconf;
2650 /* Check if any Rx parameters have been passed */
2651 if (rx_pthresh != RTE_PMD_PARAM_UNSET)
2652 port->rx_conf[qid].rx_thresh.pthresh = rx_pthresh;
2654 if (rx_hthresh != RTE_PMD_PARAM_UNSET)
2655 port->rx_conf[qid].rx_thresh.hthresh = rx_hthresh;
2657 if (rx_wthresh != RTE_PMD_PARAM_UNSET)
2658 port->rx_conf[qid].rx_thresh.wthresh = rx_wthresh;
2660 if (rx_free_thresh != RTE_PMD_PARAM_UNSET)
2661 port->rx_conf[qid].rx_free_thresh = rx_free_thresh;
2663 if (rx_drop_en != RTE_PMD_PARAM_UNSET)
2664 port->rx_conf[qid].rx_drop_en = rx_drop_en;
2666 port->nb_rx_desc[qid] = nb_rxd;
2669 for (qid = 0; qid < nb_txq; qid++) {
2670 port->tx_conf[qid] = port->dev_info.default_txconf;
2672 /* Check if any Tx parameters have been passed */
2673 if (tx_pthresh != RTE_PMD_PARAM_UNSET)
2674 port->tx_conf[qid].tx_thresh.pthresh = tx_pthresh;
2676 if (tx_hthresh != RTE_PMD_PARAM_UNSET)
2677 port->tx_conf[qid].tx_thresh.hthresh = tx_hthresh;
2679 if (tx_wthresh != RTE_PMD_PARAM_UNSET)
2680 port->tx_conf[qid].tx_thresh.wthresh = tx_wthresh;
2682 if (tx_rs_thresh != RTE_PMD_PARAM_UNSET)
2683 port->tx_conf[qid].tx_rs_thresh = tx_rs_thresh;
2685 if (tx_free_thresh != RTE_PMD_PARAM_UNSET)
2686 port->tx_conf[qid].tx_free_thresh = tx_free_thresh;
2688 port->nb_tx_desc[qid] = nb_txd;
2693 init_port_config(void)
2696 struct rte_port *port;
2698 RTE_ETH_FOREACH_DEV(pid) {
2700 port->dev_conf.fdir_conf = fdir_conf;
2701 rte_eth_dev_info_get(pid, &port->dev_info);
2703 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2704 port->dev_conf.rx_adv_conf.rss_conf.rss_hf =
2705 rss_hf & port->dev_info.flow_type_rss_offloads;
2707 port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL;
2708 port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0;
2711 if (port->dcb_flag == 0) {
2712 if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0)
2713 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
2715 port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE;
2718 rxtx_port_config(port);
2720 rte_eth_macaddr_get(pid, &port->eth_addr);
2722 map_port_queue_stats_mapping_registers(pid, port);
2723 #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS
2724 rte_pmd_ixgbe_bypass_init(pid);
2727 if (lsc_interrupt &&
2728 (rte_eth_devices[pid].data->dev_flags &
2729 RTE_ETH_DEV_INTR_LSC))
2730 port->dev_conf.intr_conf.lsc = 1;
2731 if (rmv_interrupt &&
2732 (rte_eth_devices[pid].data->dev_flags &
2733 RTE_ETH_DEV_INTR_RMV))
2734 port->dev_conf.intr_conf.rmv = 1;
2738 void set_port_slave_flag(portid_t slave_pid)
2740 struct rte_port *port;
2742 port = &ports[slave_pid];
2743 port->slave_flag = 1;
2746 void clear_port_slave_flag(portid_t slave_pid)
2748 struct rte_port *port;
2750 port = &ports[slave_pid];
2751 port->slave_flag = 0;
2754 uint8_t port_is_bonding_slave(portid_t slave_pid)
2756 struct rte_port *port;
2758 port = &ports[slave_pid];
2759 if ((rte_eth_devices[slave_pid].data->dev_flags &
2760 RTE_ETH_DEV_BONDED_SLAVE) || (port->slave_flag == 1))
2765 const uint16_t vlan_tags[] = {
2766 0, 1, 2, 3, 4, 5, 6, 7,
2767 8, 9, 10, 11, 12, 13, 14, 15,
2768 16, 17, 18, 19, 20, 21, 22, 23,
2769 24, 25, 26, 27, 28, 29, 30, 31
2773 get_eth_dcb_conf(portid_t pid, struct rte_eth_conf *eth_conf,
2774 enum dcb_mode_enable dcb_mode,
2775 enum rte_eth_nb_tcs num_tcs,
2780 struct rte_eth_rss_conf rss_conf;
2783 * Builds up the correct configuration for dcb+vt based on the vlan tags array
2784 * given above, and the number of traffic classes available for use.
2786 if (dcb_mode == DCB_VT_ENABLED) {
2787 struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
2788 ð_conf->rx_adv_conf.vmdq_dcb_conf;
2789 struct rte_eth_vmdq_dcb_tx_conf *vmdq_tx_conf =
2790 ð_conf->tx_adv_conf.vmdq_dcb_tx_conf;
2792 /* VMDQ+DCB RX and TX configurations */
2793 vmdq_rx_conf->enable_default_pool = 0;
2794 vmdq_rx_conf->default_pool = 0;
2795 vmdq_rx_conf->nb_queue_pools =
2796 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2797 vmdq_tx_conf->nb_queue_pools =
2798 (num_tcs == ETH_4_TCS ? ETH_32_POOLS : ETH_16_POOLS);
2800 vmdq_rx_conf->nb_pool_maps = vmdq_rx_conf->nb_queue_pools;
2801 for (i = 0; i < vmdq_rx_conf->nb_pool_maps; i++) {
2802 vmdq_rx_conf->pool_map[i].vlan_id = vlan_tags[i];
2803 vmdq_rx_conf->pool_map[i].pools =
2804 1 << (i % vmdq_rx_conf->nb_queue_pools);
2806 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2807 vmdq_rx_conf->dcb_tc[i] = i % num_tcs;
2808 vmdq_tx_conf->dcb_tc[i] = i % num_tcs;
2811 /* set DCB mode of RX and TX of multiple queues */
2812 eth_conf->rxmode.mq_mode = ETH_MQ_RX_VMDQ_DCB;
2813 eth_conf->txmode.mq_mode = ETH_MQ_TX_VMDQ_DCB;
2815 struct rte_eth_dcb_rx_conf *rx_conf =
2816 ð_conf->rx_adv_conf.dcb_rx_conf;
2817 struct rte_eth_dcb_tx_conf *tx_conf =
2818 ð_conf->tx_adv_conf.dcb_tx_conf;
2820 rc = rte_eth_dev_rss_hash_conf_get(pid, &rss_conf);
2824 rx_conf->nb_tcs = num_tcs;
2825 tx_conf->nb_tcs = num_tcs;
2827 for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) {
2828 rx_conf->dcb_tc[i] = i % num_tcs;
2829 tx_conf->dcb_tc[i] = i % num_tcs;
2832 eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS;
2833 eth_conf->rx_adv_conf.rss_conf = rss_conf;
2834 eth_conf->txmode.mq_mode = ETH_MQ_TX_DCB;
2838 eth_conf->dcb_capability_en =
2839 ETH_DCB_PG_SUPPORT | ETH_DCB_PFC_SUPPORT;
2841 eth_conf->dcb_capability_en = ETH_DCB_PG_SUPPORT;
2847 init_port_dcb_config(portid_t pid,
2848 enum dcb_mode_enable dcb_mode,
2849 enum rte_eth_nb_tcs num_tcs,
2852 struct rte_eth_conf port_conf;
2853 struct rte_port *rte_port;
2857 rte_port = &ports[pid];
2859 memset(&port_conf, 0, sizeof(struct rte_eth_conf));
2860 /* Enter DCB configuration status */
2863 port_conf.rxmode = rte_port->dev_conf.rxmode;
2864 port_conf.txmode = rte_port->dev_conf.txmode;
2866 /*set configuration of DCB in vt mode and DCB in non-vt mode*/
2867 retval = get_eth_dcb_conf(pid, &port_conf, dcb_mode, num_tcs, pfc_en);
2870 port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2872 /* re-configure the device . */
2873 rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf);
2875 rte_eth_dev_info_get(pid, &rte_port->dev_info);
2877 /* If dev_info.vmdq_pool_base is greater than 0,
2878 * the queue id of vmdq pools is started after pf queues.
2880 if (dcb_mode == DCB_VT_ENABLED &&
2881 rte_port->dev_info.vmdq_pool_base > 0) {
2882 printf("VMDQ_DCB multi-queue mode is nonsensical"
2883 " for port %d.", pid);
2887 /* Assume the ports in testpmd have the same dcb capability
2888 * and has the same number of rxq and txq in dcb mode
2890 if (dcb_mode == DCB_VT_ENABLED) {
2891 if (rte_port->dev_info.max_vfs > 0) {
2892 nb_rxq = rte_port->dev_info.nb_rx_queues;
2893 nb_txq = rte_port->dev_info.nb_tx_queues;
2895 nb_rxq = rte_port->dev_info.max_rx_queues;
2896 nb_txq = rte_port->dev_info.max_tx_queues;
2899 /*if vt is disabled, use all pf queues */
2900 if (rte_port->dev_info.vmdq_pool_base == 0) {
2901 nb_rxq = rte_port->dev_info.max_rx_queues;
2902 nb_txq = rte_port->dev_info.max_tx_queues;
2904 nb_rxq = (queueid_t)num_tcs;
2905 nb_txq = (queueid_t)num_tcs;
2909 rx_free_thresh = 64;
2911 memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf));
2913 rxtx_port_config(rte_port);
2915 rte_port->dev_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_FILTER;
2916 for (i = 0; i < RTE_DIM(vlan_tags); i++)
2917 rx_vft_set(pid, vlan_tags[i], 1);
2919 rte_eth_macaddr_get(pid, &rte_port->eth_addr);
2920 map_port_queue_stats_mapping_registers(pid, rte_port);
2922 rte_port->dcb_flag = 1;
2930 /* Configuration of Ethernet ports. */
2931 ports = rte_zmalloc("testpmd: ports",
2932 sizeof(struct rte_port) * RTE_MAX_ETHPORTS,
2933 RTE_CACHE_LINE_SIZE);
2934 if (ports == NULL) {
2935 rte_exit(EXIT_FAILURE,
2936 "rte_zmalloc(%d struct rte_port) failed\n",
2952 const char clr[] = { 27, '[', '2', 'J', '\0' };
2953 const char top_left[] = { 27, '[', '1', ';', '1', 'H', '\0' };
2955 /* Clear screen and move to top left */
2956 printf("%s%s", clr, top_left);
2958 printf("\nPort statistics ====================================");
2959 for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++)
2960 nic_stats_display(fwd_ports_ids[i]);
2964 signal_handler(int signum)
2966 if (signum == SIGINT || signum == SIGTERM) {
2967 printf("\nSignal %d received, preparing to exit...\n",
2969 #ifdef RTE_LIBRTE_PDUMP
2970 /* uninitialize packet capture framework */
2973 #ifdef RTE_LIBRTE_LATENCY_STATS
2974 rte_latencystats_uninit();
2977 /* Set flag to indicate the force termination. */
2979 /* exit with the expected status */
2980 signal(signum, SIG_DFL);
2981 kill(getpid(), signum);
2986 main(int argc, char** argv)
2993 signal(SIGINT, signal_handler);
2994 signal(SIGTERM, signal_handler);
2996 diag = rte_eal_init(argc, argv);
2998 rte_panic("Cannot init EAL\n");
3000 testpmd_logtype = rte_log_register("testpmd");
3001 if (testpmd_logtype < 0)
3002 rte_panic("Cannot register log type");
3003 rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG);
3005 #ifdef RTE_LIBRTE_PDUMP
3006 /* initialize packet capture framework */
3007 rte_pdump_init(NULL);
3011 RTE_ETH_FOREACH_DEV(port_id) {
3012 ports_ids[count] = port_id;
3015 nb_ports = (portid_t) count;
3017 TESTPMD_LOG(WARNING, "No probed ethernet devices\n");
3019 /* allocate port structures, and init them */
3022 set_def_fwd_config();
3024 rte_panic("Empty set of forwarding logical cores - check the "
3025 "core mask supplied in the command parameters\n");
3027 /* Bitrate/latency stats disabled by default */
3028 #ifdef RTE_LIBRTE_BITRATE
3029 bitrate_enabled = 0;
3031 #ifdef RTE_LIBRTE_LATENCY_STATS
3032 latencystats_enabled = 0;
3035 /* on FreeBSD, mlockall() is disabled by default */
3036 #ifdef RTE_EXEC_ENV_BSDAPP
3045 launch_args_parse(argc, argv);
3047 if (do_mlockall && mlockall(MCL_CURRENT | MCL_FUTURE)) {
3048 TESTPMD_LOG(NOTICE, "mlockall() failed with error \"%s\"\n",
3052 if (tx_first && interactive)
3053 rte_exit(EXIT_FAILURE, "--tx-first cannot be used on "
3054 "interactive mode.\n");
3056 if (tx_first && lsc_interrupt) {
3057 printf("Warning: lsc_interrupt needs to be off when "
3058 " using tx_first. Disabling.\n");
3062 if (!nb_rxq && !nb_txq)
3063 printf("Warning: Either rx or tx queues should be non-zero\n");
3065 if (nb_rxq > 1 && nb_rxq > nb_txq)
3066 printf("Warning: nb_rxq=%d enables RSS configuration, "
3067 "but nb_txq=%d will prevent to fully test it.\n",
3073 /* enable hot plug monitoring */
3074 ret = rte_dev_event_monitor_start();
3079 eth_dev_event_callback_register();
3083 if (start_port(RTE_PORT_ALL) != 0)
3084 rte_exit(EXIT_FAILURE, "Start ports failed\n");
3086 /* set all ports to promiscuous mode by default */
3087 RTE_ETH_FOREACH_DEV(port_id)
3088 rte_eth_promiscuous_enable(port_id);
3090 /* Init metrics library */
3091 rte_metrics_init(rte_socket_id());
3093 #ifdef RTE_LIBRTE_LATENCY_STATS
3094 if (latencystats_enabled != 0) {
3095 int ret = rte_latencystats_init(1, NULL);
3097 printf("Warning: latencystats init()"
3098 " returned error %d\n", ret);
3099 printf("Latencystats running on lcore %d\n",
3100 latencystats_lcore_id);
3104 /* Setup bitrate stats */
3105 #ifdef RTE_LIBRTE_BITRATE
3106 if (bitrate_enabled != 0) {
3107 bitrate_data = rte_stats_bitrate_create();
3108 if (bitrate_data == NULL)
3109 rte_exit(EXIT_FAILURE,
3110 "Could not allocate bitrate data.\n");
3111 rte_stats_bitrate_reg(bitrate_data);
3115 #ifdef RTE_LIBRTE_CMDLINE
3116 if (strlen(cmdline_filename) != 0)
3117 cmdline_read_from_file(cmdline_filename);
3119 if (interactive == 1) {
3121 printf("Start automatic packet forwarding\n");
3122 start_packet_forwarding(0);
3134 printf("No commandline core given, start packet forwarding\n");
3135 start_packet_forwarding(tx_first);
3136 if (stats_period != 0) {
3137 uint64_t prev_time = 0, cur_time, diff_time = 0;
3138 uint64_t timer_period;
3140 /* Convert to number of cycles */
3141 timer_period = stats_period * rte_get_timer_hz();
3143 while (f_quit == 0) {
3144 cur_time = rte_get_timer_cycles();
3145 diff_time += cur_time - prev_time;
3147 if (diff_time >= timer_period) {
3149 /* Reset the timer */
3152 /* Sleep to avoid unnecessary checks */
3153 prev_time = cur_time;
3158 printf("Press enter to exit\n");
3159 rc = read(0, &c, 1);