X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Ftestpmd.c;h=1f0d8f1afb24663cf5dd5cc5df5000c15733f89d;hb=65a7360cc3378f5b3edd59f230141462dd98cfe9;hp=91422181125dd1ddf575903e795fcbd8083ea6fd;hpb=f2b24fb03e8fcd21d10d5144ce257d0fe221adbc;p=dpdk.git diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 9142218112..1f0d8f1afb 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -76,9 +77,6 @@ #ifdef RTE_LIBRTE_IXGBE_PMD #include #endif -#ifdef RTE_LIBRTE_PMD_XENVIRT -#include -#endif #ifdef RTE_LIBRTE_PDUMP #include #endif @@ -90,7 +88,6 @@ #ifdef RTE_LIBRTE_LATENCY_STATS #include #endif -#include #include "testpmd.h" @@ -386,11 +383,12 @@ uint8_t bitrate_enabled; #endif struct gro_status gro_ports[RTE_MAX_ETHPORTS]; +uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES; /* Forward function declarations */ static void map_port_queue_stats_mapping_registers(uint8_t pi, struct rte_port *port); static void check_all_ports_link_status(uint32_t port_mask); -static int eth_event_callback(uint8_t port_id, +static int eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param, void *ret_param); @@ -400,6 +398,9 @@ static int eth_event_callback(uint8_t port_id, */ static int all_ports_started(void); +struct gso_status gso_ports[RTE_MAX_ETHPORTS]; +uint16_t gso_max_segment_size = ETHER_MAX_LEN - ETHER_CRC_LEN; + /* * Helper function to check if socket is already discovered. * If yes, return positive value. If not, return zero. @@ -463,9 +464,10 @@ static void set_default_fwd_ports_config(void) { portid_t pt_id; + int i = 0; - for (pt_id = 0; pt_id < nb_ports; pt_id++) - fwd_ports_ids[pt_id] = pt_id; + RTE_ETH_FOREACH_DEV(pt_id) + fwd_ports_ids[i++] = pt_id; nb_cfg_ports = nb_ports; nb_fwd_ports = nb_ports; @@ -497,37 +499,25 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, "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, - sizeof(struct rte_pktmbuf_pool_private), - rte_pktmbuf_pool_init, NULL, - rte_pktmbuf_init, NULL, - socket_id, 0); -#endif - - /* if the former XEN allocation failed fall back to normal allocation */ - if (rte_mp == NULL) { - 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); + 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: @@ -570,6 +560,8 @@ init_config(void) unsigned int nb_mbuf_per_pool; lcoreid_t lc_id; uint8_t port_per_socket[RTE_MAX_NUMA_NODES]; + struct rte_gro_param gro_param; + uint32_t gso_types; memset(port_per_socket,0,RTE_MAX_NUMA_NODES); @@ -654,6 +646,8 @@ init_config(void) init_port_config(); + gso_types = DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_VXLAN_TNL_TSO | + DEV_TX_OFFLOAD_GRE_TNL_TSO; /* * Records which Mbuf pool to use by each logical core, if needed. */ @@ -664,6 +658,13 @@ init_config(void) if (mbp == NULL) mbp = mbuf_pool_find(0); fwd_lcores[lc_id]->mbp = mbp; + /* initialize GSO context */ + fwd_lcores[lc_id]->gso_ctx.direct_pool = mbp; + fwd_lcores[lc_id]->gso_ctx.indirect_pool = mbp; + fwd_lcores[lc_id]->gso_ctx.gso_types = gso_types; + fwd_lcores[lc_id]->gso_ctx.gso_size = ETHER_MAX_LEN - + ETHER_CRC_LEN; + fwd_lcores[lc_id]->gso_ctx.flag = 0; } /* Configuration of packet forwarding streams. */ @@ -671,6 +672,20 @@ init_config(void) rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); fwd_config_setup(); + + /* create a gro context for each lcore */ + gro_param.gro_types = RTE_GRO_TCP_IPV4; + gro_param.max_flow_num = GRO_MAX_FLUSH_CYCLES; + gro_param.max_item_per_flow = MAX_PKT_BURST; + for (lc_id = 0; lc_id < nb_lcores; lc_id++) { + gro_param.socket_id = rte_lcore_to_socket_id( + fwd_lcores_cpuids[lc_id]); + fwd_lcores[lc_id]->gro_ctx = rte_gro_ctx_create(&gro_param); + if (fwd_lcores[lc_id]->gro_ctx == NULL) { + rte_exit(EXIT_FAILURE, + "rte_gro_ctx_create() failed\n"); + } + } } @@ -1217,6 +1232,7 @@ stop_packet_forwarding(void) #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t fwd_cycles; #endif + static const char *acc_stats_border = "+++++++++++++++"; if (test_done) { @@ -1307,6 +1323,7 @@ stop_packet_forwarding(void) fwd_port_stats_display(pt_id, &stats); } + printf("\n %s Accumulated forward statistics for all ports" "%s\n", acc_stats_border, acc_stats_border); @@ -1682,6 +1699,47 @@ close_port(portid_t pid) printf("Done\n"); } +void +reset_port(portid_t pid) +{ + int diag; + portid_t pi; + struct rte_port *port; + + if (port_id_is_invalid(pid, ENABLED_WARN)) + return; + + printf("Resetting ports...\n"); + + RTE_ETH_FOREACH_DEV(pi) { + 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; + } + + diag = rte_eth_dev_reset(pi); + if (diag == 0) { + port = &ports[pi]; + port->need_reconfig = 1; + port->need_reconfig_queues = 1; + } else { + printf("Failed to reset port %d. diag=%d\n", pi, diag); + } + } + + printf("Done\n"); +} + void attach_port(char *identifier) { @@ -1728,8 +1786,10 @@ detach_port(uint8_t port_id) if (ports[port_id].flow_list) port_flow_flush(port_id); - if (rte_eth_dev_detach(port_id, name)) + if (rte_eth_dev_detach(port_id, name)) { + RTE_LOG(ERR, USER1, "Failed to detach port '%s'\n", name); return; + } nb_ports = rte_eth_dev_count(); @@ -1773,7 +1833,8 @@ check_all_ports_link_status(uint32_t port_mask) { #define CHECK_INTERVAL 100 /* 100ms */ #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ - uint8_t portid, count, all_ports_up, print_flag = 0; + portid_t portid; + uint8_t count, all_ports_up, print_flag = 0; struct rte_eth_link link; printf("Checking link statuses...\n"); @@ -1788,14 +1849,13 @@ check_all_ports_link_status(uint32_t port_mask) /* print link status if flag set */ if (print_flag == 1) { if (link.link_status) - printf("Port %d Link Up - speed %u " - "Mbps - %s\n", (uint8_t)portid, - (unsigned)link.link_speed, + printf( + "Port%d Link Up. speed %u Mbps- %s\n", + portid, link.link_speed, (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? ("full-duplex") : ("half-duplex\n")); else - printf("Port %d Link Down\n", - (uint8_t)portid); + printf("Port %d Link Down\n", portid); continue; } /* clear all_ports_up flag if any link down */ @@ -1835,12 +1895,14 @@ rmv_event_callback(void *arg) stop_port(port_id); close_port(port_id); printf("removing device %s\n", dev->device->name); - rte_eal_dev_detach(dev->device); + if (rte_eal_dev_detach(dev->device)) + RTE_LOG(ERR, USER1, "Failed to detach device %s\n", + dev->device->name); } /* This function is used by the interrupt thread */ static int -eth_event_callback(uint8_t port_id, enum rte_eth_event_type type, void *param, +eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param, void *ret_param) { static const char * const event_desc[] = { @@ -2169,7 +2231,7 @@ init_port_dcb_config(portid_t pid, * 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_configure(pid, 0, 0, &port_conf); rte_eth_dev_info_get(pid, &rte_port->dev_info); @@ -2283,7 +2345,7 @@ int main(int argc, char** argv) { int diag; - uint8_t port_id; + portid_t port_id; signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); @@ -2292,6 +2354,11 @@ main(int argc, char** argv) if (diag < 0) rte_panic("Cannot init EAL\n"); + if (mlockall(MCL_CURRENT | MCL_FUTURE)) { + RTE_LOG(NOTICE, USER1, "mlockall() failed with error \"%s\"\n", + strerror(errno)); + } + #ifdef RTE_LIBRTE_PDUMP /* initialize packet capture framework */ rte_pdump_init(NULL); @@ -2325,6 +2392,13 @@ main(int argc, char** argv) if (tx_first && interactive) rte_exit(EXIT_FAILURE, "--tx-first cannot be used on " "interactive mode.\n"); + + if (tx_first && lsc_interrupt) { + printf("Warning: lsc_interrupt needs to be off when " + " using tx_first. Disabling.\n"); + lsc_interrupt = 0; + } + if (!nb_rxq && !nb_txq) printf("Warning: Either rx or tx queues should be non-zero\n");