X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=app%2Ftest-pmd%2Ftestpmd.c;h=9de01fed271cfd1fc69d01570ef532e14059d20f;hb=1754d8e45ba3f8b13484dee3c2b8ac4d845f2b74;hp=26a174c1e378c6c90e202b59990682ce1395456b;hpb=5129044dce1f85ce4950f31bcf90f3886466f06a;p=deb_dpdk.git diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 26a174c1..9de01fed 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -62,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -75,9 +75,11 @@ #ifdef RTE_LIBRTE_PMD_XENVIRT #include #endif +#ifdef RTE_LIBRTE_PDUMP +#include +#endif #include "testpmd.h" -#include "mempool_osdep.h" uint16_t verbose_level = 0; /**< Silent by default. */ @@ -144,7 +146,6 @@ streamid_t nb_fwd_streams; /**< Is equal to (nb_ports * nb_rxq). */ struct fwd_engine * fwd_engines[] = { &io_fwd_engine, &mac_fwd_engine, - &mac_retry_fwd_engine, &mac_swap_engine, &flow_gen_engine, &rx_only_engine, @@ -159,6 +160,9 @@ struct fwd_engine * fwd_engines[] = { struct fwd_config cur_fwd_config; struct fwd_engine *cur_fwd_eng = &io_fwd_engine; /**< IO mode by default. */ +uint32_t retry_enabled; +uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; +uint32_t burst_tx_retry_num = BURST_TX_RETRIES; uint16_t mbuf_data_size = DEFAULT_MBUF_DATA_SIZE; /**< Mbuf data space size. */ uint32_t param_total_num_mbufs = 0; /**< number of mbufs in all pools - if @@ -279,7 +283,7 @@ struct rte_eth_rxmode rx_mode = { .hw_vlan_strip = 1, /**< VLAN strip enabled. */ .hw_vlan_extend = 0, /**< Extended VLAN disabled. */ .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */ - .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */ + .hw_strip_crc = 1, /**< CRC stripping by hardware enabled. */ }; struct rte_fdir_conf fdir_conf = { @@ -416,6 +420,10 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, mb_size = sizeof(struct rte_mbuf) + mbuf_seg_size; mbuf_poolname_build(socket_id, pool_name, sizeof(pool_name)); + RTE_LOG(INFO, USER1, + "create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n", + pool_name, nb_mbuf, mbuf_seg_size, socket_id); + #ifdef RTE_LIBRTE_PMD_XENVIRT rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size, (unsigned) mb_mempool_cache, @@ -427,22 +435,33 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, /* if the former XEN allocation failed fall back to normal allocation */ if (rte_mp == NULL) { - if (mp_anon != 0) - rte_mp = mempool_anon_create(pool_name, nb_mbuf, - mb_size, (unsigned) mb_mempool_cache, - sizeof(struct rte_pktmbuf_pool_private), - rte_pktmbuf_pool_init, NULL, - rte_pktmbuf_init, NULL, - socket_id, 0); - else + if (mp_anon != 0) { + rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf, + mb_size, (unsigned) mb_mempool_cache, + sizeof(struct rte_pktmbuf_pool_private), + socket_id, 0); + if (rte_mp == NULL) + goto err; + + if (rte_mempool_populate_anon(rte_mp) == 0) { + rte_mempool_free(rte_mp); + rte_mp = NULL; + goto err; + } + rte_pktmbuf_pool_init(rte_mp, NULL); + rte_mempool_obj_iter(rte_mp, rte_pktmbuf_init, NULL); + } else { /* wrapper to rte_mempool_create() */ rte_mp = rte_pktmbuf_pool_create(pool_name, nb_mbuf, mb_mempool_cache, 0, mbuf_seg_size, socket_id); + } } +err: if (rte_mp == NULL) { - rte_exit(EXIT_FAILURE, "Creation of mbuf pool for socket %u " - "failed\n", socket_id); + rte_exit(EXIT_FAILURE, + "Creation of mbuf pool for socket %u failed: %s\n", + socket_id, rte_strerror(rte_errno)); } else if (verbose_level > 0) { rte_mempool_dump(stdout, rte_mp); } @@ -499,34 +518,6 @@ init_config(void) fwd_lcores[lc_id]->cpuid_idx = lc_id; } - /* - * Create pools of mbuf. - * If NUMA support is disabled, create a single pool of mbuf in - * socket 0 memory by default. - * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. - * - * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and - * nb_txd can be configured at run time. - */ - if (param_total_num_mbufs) - nb_mbuf_per_pool = param_total_num_mbufs; - else { - nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + (nb_lcores * mb_mempool_cache) - + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; - - if (!numa_support) - nb_mbuf_per_pool = - (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); - } - - if (!numa_support) { - if (socket_num == UMA_NO_CONFIG) - mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); - else - mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, - socket_num); - } - FOREACH_PORT(pid, ports) { port = &ports[pid]; rte_eth_dev_info_get(pid, &port->dev_info); @@ -549,20 +540,37 @@ init_config(void) port->need_reconfig_queues = 1; } + /* + * Create pools of mbuf. + * If NUMA support is disabled, create a single pool of mbuf in + * socket 0 memory by default. + * Otherwise, create a pool of mbuf in the memory of sockets 0 and 1. + * + * Use the maximum value of nb_rxd and nb_txd here, then nb_rxd and + * nb_txd can be configured at run time. + */ + if (param_total_num_mbufs) + nb_mbuf_per_pool = param_total_num_mbufs; + else { + nb_mbuf_per_pool = RTE_TEST_RX_DESC_MAX + + (nb_lcores * mb_mempool_cache) + + RTE_TEST_TX_DESC_MAX + MAX_PKT_BURST; + nb_mbuf_per_pool *= RTE_MAX_ETHPORTS; + } + if (numa_support) { uint8_t i; - unsigned int nb_mbuf; - if (param_total_num_mbufs) - nb_mbuf_per_pool = nb_mbuf_per_pool/nb_ports; - - for (i = 0; i < max_socket; i++) { - nb_mbuf = (nb_mbuf_per_pool * RTE_MAX_ETHPORTS); - if (nb_mbuf) - mbuf_pool_create(mbuf_data_size, - nb_mbuf,i); - } + for (i = 0; i < max_socket; i++) + mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, i); + } else { + if (socket_num == UMA_NO_CONFIG) + mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, 0); + else + mbuf_pool_create(mbuf_data_size, nb_mbuf_per_pool, + socket_num); } + init_port_config(); /* @@ -580,6 +588,8 @@ init_config(void) /* Configuration of packet forwarding streams. */ if (init_fwd_streams() < 0) rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); + + fwd_config_setup(); } @@ -859,17 +869,35 @@ flush_fwd_rx_queues(void) uint16_t nb_rx; uint16_t i; uint8_t j; + uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0; + uint64_t timer_period; + + /* convert to number of cycles */ + timer_period = rte_get_timer_hz(); /* 1 second timeout */ for (j = 0; j < 2; j++) { for (rxp = 0; rxp < cur_fwd_config.nb_fwd_ports; rxp++) { for (rxq = 0; rxq < nb_rxq; rxq++) { port_id = fwd_ports_ids[rxp]; + /** + * testpmd can stuck in the below do while loop + * if rte_eth_rx_burst() always returns nonzero + * packets. So timer is added to exit this loop + * after 1sec timer expiry. + */ + prev_tsc = rte_rdtsc(); do { nb_rx = rte_eth_rx_burst(port_id, rxq, pkts_burst, MAX_PKT_BURST); for (i = 0; i < nb_rx; i++) rte_pktmbuf_free(pkts_burst[i]); - } while (nb_rx > 0); + + cur_tsc = rte_rdtsc(); + diff_tsc = cur_tsc - prev_tsc; + timer_tsc += diff_tsc; + } while ((nb_rx > 0) && + (timer_tsc < timer_period)); + timer_tsc = 0; } } rte_delay_ms(10); /* wait 10 milli-seconds before retrying */ @@ -981,6 +1009,12 @@ start_packet_forwarding(int with_tx_first) printf("Packet forwarding already started\n"); return; } + + if (init_fwd_streams() < 0) { + printf("Fail from init_fwd_streams()\n"); + return; + } + if(dcb_test) { for (i = 0; i < nb_fwd_ports; i++) { pt_id = fwd_ports_ids[i]; @@ -1003,6 +1037,7 @@ start_packet_forwarding(int with_tx_first) flush_fwd_rx_queues(); fwd_config_setup(); + pkt_fwd_config_display(&cur_fwd_config); rxtx_config_display(); for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { @@ -1036,8 +1071,11 @@ start_packet_forwarding(int with_tx_first) for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) (*port_fwd_begin)(fwd_ports_ids[i]); } - launch_packet_forwarding(run_one_txonly_burst_on_core); - rte_eal_mp_wait_lcore(); + while (with_tx_first--) { + launch_packet_forwarding( + run_one_txonly_burst_on_core); + rte_eal_mp_wait_lcore(); + } port_fwd_end = tx_only_engine.port_fwd_end; if (port_fwd_end != NULL) { for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) @@ -1070,10 +1108,6 @@ stop_packet_forwarding(void) #endif static const char *acc_stats_border = "+++++++++++++++"; - if (all_ports_started() == 0) { - printf("Not all ports were started\n"); - return; - } if (test_done) { printf("Packet forwarding not started\n"); return; @@ -1268,19 +1302,9 @@ start_port(portid_t pid) struct rte_port *port; struct ether_addr mac_addr; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return -1; - } - if (port_id_is_invalid(pid, ENABLED_WARN)) return 0; - if (init_fwd_streams() < 0) { - printf("Fail from init_fwd_streams()\n"); - return -1; - } - if(dcb_config) dcb_test = 1; FOREACH_PORT(pi, ports) { @@ -1351,7 +1375,7 @@ start_port(portid_t pid) if (mp == NULL) { printf("Failed to setup RX queue:" "No mempool allocation" - "on the socket %d\n", + " on the socket %d\n", rxring_numa[pi]); return -1; } @@ -1359,17 +1383,23 @@ start_port(portid_t pid) diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd,rxring_numa[pi], &(port->rx_conf),mp); - } - else + } else { + struct rte_mempool *mp = + mbuf_pool_find(port->socket_id); + if (mp == NULL) { + printf("Failed to setup RX queue:" + "No mempool allocation" + " on the socket %d\n", + port->socket_id); + return -1; + } diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd,port->socket_id, - &(port->rx_conf), - mbuf_pool_find(port->socket_id)); - + &(port->rx_conf), mp); + } if (diag == 0) continue; - /* Fail to setup rx queue, return */ if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_HANDLING, @@ -1424,10 +1454,6 @@ stop_port(portid_t pid) struct rte_port *port; int need_check_link_status = 0; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } if (dcb_test) { dcb_test = 0; dcb_config = 0; @@ -1442,6 +1468,16 @@ stop_port(portid_t pid) if (pid != pi && pid != (portid_t)RTE_PORT_ALL) continue; + if (port_is_forwarding(pi) != 0 && test_done == 0) { + printf("Please remove port %d from forwarding configuration.\n", pi); + continue; + } + + if (port_is_bonding_slave(pi)) { + printf("Please remove port %d from bonded device.\n", pi); + continue; + } + port = &ports[pi]; if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, RTE_PORT_HANDLING) == 0) @@ -1466,11 +1502,6 @@ close_port(portid_t pid) portid_t pi; struct rte_port *port; - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } - if (port_id_is_invalid(pid, ENABLED_WARN)) return; @@ -1480,6 +1511,16 @@ close_port(portid_t pid) if (pid != pi && pid != (portid_t)RTE_PORT_ALL) continue; + if (port_is_forwarding(pi) != 0 && test_done == 0) { + printf("Please remove port %d from forwarding configuration.\n", pi); + continue; + } + + if (port_is_bonding_slave(pi)) { + printf("Please remove port %d from bonded device.\n", pi); + continue; + } + port = &ports[pi]; if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_CLOSED, RTE_PORT_CLOSED) == 1) { @@ -1497,7 +1538,7 @@ close_port(portid_t pid) if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_HANDLING, RTE_PORT_CLOSED) == 0) - printf("Port %d can not be set into stopped\n", pi); + printf("Port %d cannot be set to closed\n", pi); } printf("Done\n"); @@ -1506,7 +1547,8 @@ close_port(portid_t pid) void attach_port(char *identifier) { - portid_t i, j, pi = 0; + portid_t pi = 0; + unsigned int socket_id; printf("Attaching a new port...\n"); @@ -1515,30 +1557,19 @@ attach_port(char *identifier) return; } - if (test_done == 0) { - printf("Please stop forwarding first\n"); - return; - } - if (rte_eth_dev_attach(identifier, &pi)) return; ports[pi].enabled = 1; - reconfig(pi, rte_eth_dev_socket_id(pi)); + socket_id = (unsigned)rte_eth_dev_socket_id(pi); + /* if socket_id is invalid, set to 0 */ + if (check_socket_id(socket_id) < 0) + socket_id = 0; + reconfig(pi, socket_id); rte_eth_promiscuous_enable(pi); nb_ports = rte_eth_dev_count(); - /* set_default_fwd_ports_config(); */ - memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids)); - i = 0; - FOREACH_PORT(j, ports) { - fwd_ports_ids[i] = j; - i++; - } - nb_cfg_ports = nb_ports; - nb_fwd_ports++; - ports[pi].port_status = RTE_PORT_STOPPED; printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports); @@ -1548,7 +1579,6 @@ attach_port(char *identifier) void detach_port(uint8_t port_id) { - portid_t i, pi = 0; char name[RTE_ETH_NAME_MAX_LEN]; printf("Detaching a port...\n"); @@ -1564,16 +1594,6 @@ detach_port(uint8_t port_id) ports[port_id].enabled = 0; nb_ports = rte_eth_dev_count(); - /* set_default_fwd_ports_config(); */ - memset(fwd_ports_ids, 0, sizeof(fwd_ports_ids)); - i = 0; - FOREACH_PORT(pi, ports) { - fwd_ports_ids[i] = pi; - i++; - } - nb_cfg_ports = nb_ports; - nb_fwd_ports--; - printf("Port '%s' is detached. Now total ports is %d\n", name, nb_ports); printf("Done\n"); @@ -1798,24 +1818,13 @@ init_port_config(void) port->dev_conf.rx_adv_conf.rss_conf.rss_hf = 0; } - if (port->dcb_flag == 0 && port->dev_info.max_vfs == 0) { + if (port->dcb_flag == 0) { if( port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; else port->dev_conf.rxmode.mq_mode = ETH_MQ_RX_NONE; } - if (port->dev_info.max_vfs != 0) { - if (port->dev_conf.rx_adv_conf.rss_conf.rss_hf != 0) - port->dev_conf.rxmode.mq_mode = - ETH_MQ_RX_VMDQ_RSS; - else - port->dev_conf.rxmode.mq_mode = - ETH_MQ_RX_NONE; - - port->dev_conf.txmode.mq_mode = ETH_MQ_TX_NONE; - } - rxtx_port_config(port); rte_eth_macaddr_get(pid, &port->eth_addr); @@ -1843,6 +1852,14 @@ void clear_port_slave_flag(portid_t slave_pid) port->slave_flag = 0; } +uint8_t port_is_bonding_slave(portid_t slave_pid) +{ + struct rte_port *port; + + port = &ports[slave_pid]; + return port->slave_flag; +} + const uint16_t vlan_tags[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -1883,8 +1900,8 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf, 1 << (i % vmdq_rx_conf->nb_queue_pools); } for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { - vmdq_rx_conf->dcb_tc[i] = i; - vmdq_tx_conf->dcb_tc[i] = i; + vmdq_rx_conf->dcb_tc[i] = i % num_tcs; + vmdq_tx_conf->dcb_tc[i] = i % num_tcs; } /* set DCB mode of RX and TX of multiple queues */ @@ -1899,9 +1916,9 @@ get_eth_dcb_conf(struct rte_eth_conf *eth_conf, rx_conf->nb_tcs = num_tcs; tx_conf->nb_tcs = num_tcs; - for (i = 0; i < num_tcs; i++) { - rx_conf->dcb_tc[i] = i; - tx_conf->dcb_tc[i] = i; + for (i = 0; i < ETH_DCB_NUM_USER_PRIORITIES; i++) { + rx_conf->dcb_tc[i] = i % num_tcs; + tx_conf->dcb_tc[i] = i % num_tcs; } eth_conf->rxmode.mq_mode = ETH_MQ_RX_DCB_RSS; eth_conf->rx_adv_conf.rss_conf.rss_hf = rss_hf; @@ -1924,17 +1941,36 @@ init_port_dcb_config(portid_t pid, uint8_t pfc_en) { struct rte_eth_conf port_conf; - struct rte_eth_dev_info dev_info; struct rte_port *rte_port; int retval; uint16_t i; - rte_eth_dev_info_get(pid, &dev_info); + rte_port = &ports[pid]; + + memset(&port_conf, 0, sizeof(struct rte_eth_conf)); + /* Enter DCB configuration status */ + dcb_config = 1; + + /*set configuration of DCB in vt mode and DCB in non-vt mode*/ + retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); + if (retval < 0) + return retval; + port_conf.rxmode.hw_vlan_filter = 1; + + /** + * Write the configuration into the device. + * Set the numbers of RX & TX queues to 0, so + * the RX & TX queues will not be setup. + */ + (void)rte_eth_dev_configure(pid, 0, 0, &port_conf); + + rte_eth_dev_info_get(pid, &rte_port->dev_info); /* If dev_info.vmdq_pool_base is greater than 0, * the queue id of vmdq pools is started after pf queues. */ - if (dcb_mode == DCB_VT_ENABLED && dev_info.vmdq_pool_base > 0) { + if (dcb_mode == DCB_VT_ENABLED && + rte_port->dev_info.vmdq_pool_base > 0) { printf("VMDQ_DCB multi-queue mode is nonsensical" " for port %d.", pid); return -1; @@ -1944,13 +1980,18 @@ init_port_dcb_config(portid_t pid, * and has the same number of rxq and txq in dcb mode */ if (dcb_mode == DCB_VT_ENABLED) { - nb_rxq = dev_info.max_rx_queues; - nb_txq = dev_info.max_tx_queues; + if (rte_port->dev_info.max_vfs > 0) { + nb_rxq = rte_port->dev_info.nb_rx_queues; + nb_txq = rte_port->dev_info.nb_tx_queues; + } else { + nb_rxq = rte_port->dev_info.max_rx_queues; + nb_txq = rte_port->dev_info.max_tx_queues; + } } else { /*if vt is disabled, use all pf queues */ - if (dev_info.vmdq_pool_base == 0) { - nb_rxq = dev_info.max_rx_queues; - nb_txq = dev_info.max_tx_queues; + if (rte_port->dev_info.vmdq_pool_base == 0) { + nb_rxq = rte_port->dev_info.max_rx_queues; + nb_txq = rte_port->dev_info.max_tx_queues; } else { nb_rxq = (queueid_t)num_tcs; nb_txq = (queueid_t)num_tcs; @@ -1959,16 +2000,6 @@ init_port_dcb_config(portid_t pid, } rx_free_thresh = 64; - memset(&port_conf, 0, sizeof(struct rte_eth_conf)); - /* Enter DCB configuration status */ - dcb_config = 1; - - /*set configuration of DCB in vt mode and DCB in non-vt mode*/ - retval = get_eth_dcb_conf(&port_conf, dcb_mode, num_tcs, pfc_en); - if (retval < 0) - return retval; - - rte_port = &ports[pid]; memcpy(&rte_port->dev_conf, &port_conf, sizeof(struct rte_eth_conf)); rxtx_port_config(rte_port); @@ -2018,6 +2049,10 @@ signal_handler(int signum) if (signum == SIGINT || signum == SIGTERM) { printf("\nSignal %d received, preparing to exit...\n", signum); +#ifdef RTE_LIBRTE_PDUMP + /* uninitialize packet capture framework */ + rte_pdump_uninit(); +#endif force_quit(); /* exit with the expected status */ signal(signum, SIG_DFL); @@ -2038,6 +2073,11 @@ main(int argc, char** argv) if (diag < 0) rte_panic("Cannot init EAL\n"); +#ifdef RTE_LIBRTE_PDUMP + /* initialize packet capture framework */ + rte_pdump_init(NULL); +#endif + nb_ports = (portid_t) rte_eth_dev_count(); if (nb_ports == 0) RTE_LOG(WARNING, EAL, "No probed ethernet devices\n"); @@ -2078,6 +2118,7 @@ main(int argc, char** argv) start_packet_forwarding(0); } prompt(); + pmd_test_exit(); } else #endif {