X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Ftestpmd.c;h=2e828e45821111d4a63ab79a64cceffbf26fb692;hb=ce8d561418d45cca86755be0f3cabc7a1a9dba4b;hp=2365a5d193b8cd4daafb505876d4e8828b7f49a0;hpb=c87988187fdb35cfc7ee1624159ee273e587ac9d;p=dpdk.git diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 2365a5d193..2e828e4582 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -204,6 +204,11 @@ struct rte_eth_thresh tx_thresh = { */ uint16_t rx_free_thresh = 0; /* Immediately free RX descriptors by default. */ +/* + * Configurable value of RX drop enable. + */ +uint8_t rx_drop_en = 0; /* Drop packets when no descriptors for queue. */ + /* * Configurable value of TX free threshold. */ @@ -214,6 +219,11 @@ uint16_t tx_free_thresh = 0; /* Use default values. */ */ uint16_t tx_rs_thresh = 0; /* Use default values. */ +/* + * Configurable value of TX queue flags. + */ +uint32_t txq_flags = 0; /* No flags set. */ + /* * Receive Side Scaling (RSS) configuration. */ @@ -260,6 +270,13 @@ uint16_t nb_rx_queue_stats_mappings = 0; /* 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(uint8_t port_num, uint32_t port_mask); + +/* + * Check if all the ports are started. + * If yes, return positive value. If not, return zero. + */ +static int all_ports_started(void); /* * Setup default configuration. @@ -394,35 +411,35 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf, testpmd_mbuf_ctor, &mb_ctor_arg, socket_id, 0); 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\n", socket_id); } } static void init_config(void) { + portid_t pid; struct rte_port *port; struct rte_mempool *mbp; unsigned int nb_mbuf_per_pool; - streamid_t sm_id; lcoreid_t lc_id; - portid_t pt_id; /* Configuration of logical cores. */ fwd_lcores = rte_zmalloc("testpmd: fwd_lcores", sizeof(struct fwd_lcore *) * nb_lcores, CACHE_LINE_SIZE); if (fwd_lcores == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) failed\n", - nb_lcores); + rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_lcore *)) " + "failed\n", nb_lcores); } for (lc_id = 0; lc_id < nb_lcores; lc_id++) { fwd_lcores[lc_id] = rte_zmalloc("testpmd: struct fwd_lcore", sizeof(struct fwd_lcore), CACHE_LINE_SIZE); if (fwd_lcores[lc_id] == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) failed\n"); + rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_lcore) " + "failed\n"); } fwd_lcores[lc_id]->cpuid_idx = lc_id; } @@ -466,48 +483,86 @@ init_config(void) sizeof(struct rte_port) * nb_ports, CACHE_LINE_SIZE); if (ports == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) failed\n", - nb_ports); + rte_exit(EXIT_FAILURE, "rte_zmalloc(%d struct rte_port) " + "failed\n", nb_ports); + } + + for (pid = 0; pid < nb_ports; pid++) { + port = &ports[pid]; + rte_eth_dev_info_get(pid, &port->dev_info); + + /* set flag to initialize port/queue */ + port->need_reconfig = 1; + port->need_reconfig_queues = 1; } - port = ports; - for (pt_id = 0; pt_id < nb_ports; pt_id++, port++) { - rte_eth_dev_info_get(pt_id, &port->dev_info); + + init_port_config(); + + /* Configuration of packet forwarding streams. */ + if (init_fwd_streams() < 0) + rte_exit(EXIT_FAILURE, "FAIL from init_fwd_streams()\n"); +} + +int +init_fwd_streams(void) +{ + portid_t pid; + struct rte_port *port; + streamid_t sm_id, nb_fwd_streams_new; + + /* set socket id according to numa or not */ + for (pid = 0; pid < nb_ports; pid++) { + port = &ports[pid]; if (nb_rxq > port->dev_info.max_rx_queues) { - rte_exit(EXIT_FAILURE, "Port %d: max RX queues %d < nb_rxq %d\n", - (int) pt_id, - (int) port->dev_info.max_rx_queues, - (int) nb_rxq); + printf("Fail: nb_rxq(%d) is greater than " + "max_rx_queues(%d)\n", nb_rxq, + port->dev_info.max_rx_queues); + return -1; } if (nb_txq > port->dev_info.max_tx_queues) { - rte_exit(EXIT_FAILURE, "Port %d: max TX queues %d < nb_txq %d\n", - (int) pt_id, - (int) port->dev_info.max_tx_queues, - (int) nb_txq); + printf("Fail: nb_txq(%d) is greater than " + "max_tx_queues(%d)\n", nb_txq, + port->dev_info.max_tx_queues); + return -1; } - if (numa_support) - port->socket_id = (pt_id < (nb_ports >> 1)) ? 0 : 1; + port->socket_id = (pid < (nb_ports >> 1)) ? 0 : 1; else port->socket_id = 0; } - /* Configuration of packet forwarding streams. */ - nb_fwd_streams = (streamid_t) (nb_ports * nb_rxq); - fwd_streams = rte_zmalloc("testpmd: fwd_streams", - sizeof(struct fwd_stream *) * nb_fwd_streams, - CACHE_LINE_SIZE); - if (fwd_streams == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) failed\n", - nb_fwd_streams); + nb_fwd_streams_new = (streamid_t)(nb_ports * nb_rxq); + if (nb_fwd_streams_new == nb_fwd_streams) + return 0; + /* clear the old */ + if (fwd_streams != NULL) { + for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { + if (fwd_streams[sm_id] == NULL) + continue; + rte_free(fwd_streams[sm_id]); + fwd_streams[sm_id] = NULL; + } + rte_free(fwd_streams); + fwd_streams = NULL; } + + /* init new */ + nb_fwd_streams = nb_fwd_streams_new; + fwd_streams = rte_zmalloc("testpmd: fwd_streams", + sizeof(struct fwd_stream *) * nb_fwd_streams, CACHE_LINE_SIZE); + if (fwd_streams == NULL) + rte_exit(EXIT_FAILURE, "rte_zmalloc(%d (struct fwd_stream *)) " + "failed\n", nb_fwd_streams); + for (sm_id = 0; sm_id < nb_fwd_streams; sm_id++) { fwd_streams[sm_id] = rte_zmalloc("testpmd: struct fwd_stream", - sizeof(struct fwd_stream), - CACHE_LINE_SIZE); - if (fwd_streams[sm_id] == NULL) { - rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream) failed\n"); - } + sizeof(struct fwd_stream), CACHE_LINE_SIZE); + if (fwd_streams[sm_id] == NULL) + rte_exit(EXIT_FAILURE, "rte_zmalloc(struct fwd_stream)" + " failed\n"); } + + return 0; } #ifdef RTE_TEST_PMD_RECORD_BURST_STATS @@ -746,6 +801,10 @@ start_packet_forwarding(int with_tx_first) portid_t pt_id; streamid_t sm_id; + if (all_ports_started() == 0) { + printf("Not all ports were started\n"); + return; + } if (test_done == 0) { printf("Packet forwarding already started\n"); return; @@ -818,6 +877,10 @@ 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; @@ -931,6 +994,231 @@ stop_packet_forwarding(void) test_done = 1; } +static int +all_ports_started(void) +{ + portid_t pi; + struct rte_port *port; + + for (pi = 0; pi < nb_ports; pi++) { + port = &ports[pi]; + /* Check if there is a port which is not started */ + if (port->port_status != RTE_PORT_STARTED) + return 0; + } + + /* No port is not started */ + return 1; +} + +void +start_port(portid_t pid) +{ + int diag, need_check_link_status = 0; + portid_t pi; + queueid_t qi; + struct rte_port *port; + + if (test_done == 0) { + printf("Please stop forwarding first\n"); + return; + } + + if (init_fwd_streams() < 0) { + printf("Fail from init_fwd_streams()\n"); + return; + } + + if(dcb_config) + dcb_test = 1; + for (pi = 0; pi < nb_ports; pi++) { + if (pid < nb_ports && pid != pi) + continue; + + port = &ports[pi]; + if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STOPPED, + RTE_PORT_HANDLING) == 0) { + printf("Port %d is now not stopped\n", pi); + continue; + } + + if (port->need_reconfig > 0) { + port->need_reconfig = 0; + + printf("Configuring Port %d\n", pi); + /* configure port */ + diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, + &(port->dev_conf)); + if (diag != 0) { + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set back " + "to stopped\n", pi); + printf("Fail to configure port %d\n", pi); + /* try to reconfigure port next time */ + port->need_reconfig = 1; + return; + } + } + + if (port->need_reconfig_queues > 0) { + port->need_reconfig_queues = 0; + + /* setup tx queues */ + for (qi = 0; qi < nb_txq; qi++) { + diag = rte_eth_tx_queue_setup(pi, qi, nb_txd, + port->socket_id, &(port->tx_conf)); + if (diag == 0) + continue; + + /* Fail to setup tx queue, return */ + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, + RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set back " + "to stopped\n", pi); + printf("Fail to configure port %d tx queues\n", pi); + /* try to reconfigure queues next time */ + port->need_reconfig_queues = 1; + return; + } + /* setup rx queues */ + for (qi = 0; qi < nb_rxq; qi++) { + diag = rte_eth_rx_queue_setup(pi, qi, nb_rxd, + port->socket_id, &(port->rx_conf), + mbuf_pool_find(port->socket_id)); + if (diag == 0) + continue; + + /* Fail to setup rx queue, return */ + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, + RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set back " + "to stopped\n", pi); + printf("Fail to configure port %d rx queues\n", pi); + /* try to reconfigure queues next time */ + port->need_reconfig_queues = 1; + return; + } + } + + /* start port */ + if (rte_eth_dev_start(pi) < 0) { + printf("Fail to start port %d\n", pi); + + /* Fail to setup rx queue, return */ + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set back to " + "stopped\n", pi); + continue; + } + + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) + printf("Port %d can not be set into started\n", pi); + + /* at least one port started, need checking link status */ + need_check_link_status = 1; + } + + if (need_check_link_status) + check_all_ports_link_status(nb_ports, RTE_PORT_ALL); + else + printf("Please stop the ports first\n"); + + printf("Done\n"); +} + +void +stop_port(portid_t pid) +{ + portid_t pi; + 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; + } + printf("Stopping ports...\n"); + + for (pi = 0; pi < nb_ports; pi++) { + if (pid < nb_ports && pid != pi) + continue; + + port = &ports[pi]; + if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_STARTED, + RTE_PORT_HANDLING) == 0) + continue; + + rte_eth_dev_stop(pi); + + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) + printf("Port %d can not be set into stopped\n", pi); + need_check_link_status = 1; + } + if (need_check_link_status) + check_all_ports_link_status(nb_ports, RTE_PORT_ALL); + + printf("Done\n"); +} + +void +close_port(portid_t pid) +{ + portid_t pi; + struct rte_port *port; + + if (test_done == 0) { + printf("Please stop forwarding first\n"); + return; + } + + printf("Closing ports...\n"); + + for (pi = 0; pi < nb_ports; pi++) { + if (pid < nb_ports && pid != pi) + continue; + + port = &ports[pi]; + if (rte_atomic16_cmpset(&(port->port_status), + RTE_PORT_STOPPED, RTE_PORT_HANDLING) == 0) { + printf("Port %d is now not stopped\n", pi); + continue; + } + + rte_eth_dev_close(pi); + + 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("Done\n"); +} + +int +all_ports_stopped(void) +{ + portid_t pi; + struct rte_port *port; + + for (pi = 0; pi < nb_ports; pi++) { + port = &ports[pi]; + if (port->port_status != RTE_PORT_STOPPED) + return 0; + } + + return 1; +} + void pmd_test_exit(void) { @@ -953,11 +1241,57 @@ struct pmd_test_command { #define PMD_TEST_CMD_NB (sizeof(pmd_test_menu) / sizeof(pmd_test_menu[0])) +/* Check the link status of all ports in up to 9s, and print them finally */ static void -fatal_init_error(const char *func_name, uint8_t port_id, int diag) +check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) { - rte_panic("%s(port_id=%d) failed - diag=%d\n", - func_name, port_id, diag); +#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; + struct rte_eth_link link; + + printf("Checking link statuses...\n"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + all_ports_up = 1; + for (portid = 0; portid < port_num; portid++) { + if ((port_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + /* 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, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + else + printf("Port %d Link Down\n", + (uint8_t)portid); + continue; + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == 0) { + all_ports_up = 0; + break; + } + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + + if (all_ports_up == 0) { + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + } + } } static void @@ -1096,8 +1430,11 @@ main(int argc, char** argv) nb_rxq, nb_txq); init_config(); + start_port(RTE_PORT_ALL); - init_ports(); + /* set all ports to promiscuous mode by default */ + for (port_id = 0; port_id < nb_ports; port_id++) + rte_eth_promiscuous_enable(port_id); if (interactive == 1) prompt();