X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Ftestpmd.c;h=b3746822366fa7c1bfcd4fbd5f9f4e6976d2c14b;hb=9e6b36c34ce928d13a5182e8e76580058366bf7c;hp=518865a7db25cb104d82e39540cc83b9b2d03806;hpb=6937d2103e22778c4181a10092663f7ed61d17dc;p=dpdk.git diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 518865a7db..b374682236 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -235,6 +234,7 @@ uint8_t dcb_test = 0; /* * Configurable number of RX/TX queues. */ +queueid_t nb_hairpinq; /**< Number of hairpin queues per port. */ queueid_t nb_rxq = 1; /**< Number of RX queues per port. */ queueid_t nb_txq = 1; /**< Number of TX queues per port. */ @@ -359,6 +359,9 @@ uint8_t hot_plug = 0; /**< hotplug disabled by default. */ /* After attach, port setup is called on event or by iterator */ bool setup_on_probe_event = true; +/* Clear ptypes on port initialization. */ +uint8_t clear_ptypes = true; + /* Pretty printing of ethdev events */ static const char * const eth_event_desc[] = { [RTE_ETH_EVENT_UNKNOWN] = "unknown", @@ -478,41 +481,6 @@ uint8_t bitrate_enabled; struct gro_status gro_ports[RTE_MAX_ETHPORTS]; uint8_t gro_flush_cycles = GRO_DEFAULT_FLUSH_CYCLES; -struct vxlan_encap_conf vxlan_encap_conf = { - .select_ipv4 = 1, - .select_vlan = 0, - .select_tos_ttl = 0, - .vni = "\x00\x00\x00", - .udp_src = 0, - .udp_dst = RTE_BE16(4789), - .ipv4_src = RTE_IPV4(127, 0, 0, 1), - .ipv4_dst = RTE_IPV4(255, 255, 255, 255), - .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x01", - .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x11\x11", - .vlan_tci = 0, - .ip_tos = 0, - .ip_ttl = 255, - .eth_src = "\x00\x00\x00\x00\x00\x00", - .eth_dst = "\xff\xff\xff\xff\xff\xff", -}; - -struct nvgre_encap_conf nvgre_encap_conf = { - .select_ipv4 = 1, - .select_vlan = 0, - .tni = "\x00\x00\x00", - .ipv4_src = RTE_IPV4(127, 0, 0, 1), - .ipv4_dst = RTE_IPV4(255, 255, 255, 255), - .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x01", - .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x11\x11", - .vlan_tci = 0, - .eth_src = "\x00\x00\x00\x00\x00\x00", - .eth_dst = "\xff\xff\xff\xff\xff\xff", -}; - /* Forward function declarations */ static void setup_attached_port(portid_t pi); static void map_port_queue_stats_mapping_registers(portid_t pi, @@ -1011,18 +979,22 @@ check_socket_id(const unsigned int socket_id) queueid_t get_allowed_max_nb_rxq(portid_t *pid) { - queueid_t allowed_max_rxq = MAX_QUEUE_ID; + queueid_t allowed_max_rxq = RTE_MAX_QUEUES_PER_PORT; + bool max_rxq_valid = false; portid_t pi; struct rte_eth_dev_info dev_info; RTE_ETH_FOREACH_DEV(pi) { - rte_eth_dev_info_get(pi, &dev_info); + if (eth_dev_info_get_print_err(pi, &dev_info) != 0) + continue; + + max_rxq_valid = true; if (dev_info.max_rx_queues < allowed_max_rxq) { allowed_max_rxq = dev_info.max_rx_queues; *pid = pi; } } - return allowed_max_rxq; + return max_rxq_valid ? allowed_max_rxq : 0; } /* @@ -1057,18 +1029,22 @@ check_nb_rxq(queueid_t rxq) queueid_t get_allowed_max_nb_txq(portid_t *pid) { - queueid_t allowed_max_txq = MAX_QUEUE_ID; + queueid_t allowed_max_txq = RTE_MAX_QUEUES_PER_PORT; + bool max_txq_valid = false; portid_t pi; struct rte_eth_dev_info dev_info; RTE_ETH_FOREACH_DEV(pi) { - rte_eth_dev_info_get(pi, &dev_info); + if (eth_dev_info_get_print_err(pi, &dev_info) != 0) + continue; + + max_txq_valid = true; if (dev_info.max_tx_queues < allowed_max_txq) { allowed_max_txq = dev_info.max_tx_queues; *pid = pi; } } - return allowed_max_txq; + return max_txq_valid ? allowed_max_txq : 0; } /* @@ -1095,6 +1071,53 @@ check_nb_txq(queueid_t txq) return 0; } +/* + * Get the allowed maximum number of hairpin queues. + * *pid return the port id which has minimal value of + * max_hairpin_queues in all ports. + */ +queueid_t +get_allowed_max_nb_hairpinq(portid_t *pid) +{ + queueid_t allowed_max_hairpinq = RTE_MAX_QUEUES_PER_PORT; + portid_t pi; + struct rte_eth_hairpin_cap cap; + + RTE_ETH_FOREACH_DEV(pi) { + if (rte_eth_dev_hairpin_capability_get(pi, &cap) != 0) { + *pid = pi; + return 0; + } + if (cap.max_nb_queues < allowed_max_hairpinq) { + allowed_max_hairpinq = cap.max_nb_queues; + *pid = pi; + } + } + return allowed_max_hairpinq; +} + +/* + * Check input hairpin is valid or not. + * If input hairpin is not greater than any of maximum number + * of hairpin queues of all ports, it is valid. + * if valid, return 0, else return -1 + */ +int +check_nb_hairpinq(queueid_t hairpinq) +{ + queueid_t allowed_max_hairpinq; + portid_t pid = 0; + + allowed_max_hairpinq = get_allowed_max_nb_hairpinq(&pid); + if (hairpinq > allowed_max_hairpinq) { + printf("Fail: input hairpin (%u) can't be greater " + "than max_hairpin_queues (%u) of port %u\n", + hairpinq, allowed_max_hairpinq, pid); + return -1; + } + return 0; +} + static void init_config(void) { @@ -1109,6 +1132,7 @@ init_config(void) uint16_t data_size; bool warning = 0; int k; + int ret; memset(port_per_socket,0,RTE_MAX_NUMA_NODES); @@ -1136,16 +1160,16 @@ init_config(void) /* Apply default TxRx configuration for all ports */ port->dev_conf.txmode = tx_mode; port->dev_conf.rxmode = rx_mode; - rte_eth_dev_info_get(pid, &port->dev_info); + + ret = eth_dev_info_get_print_err(pid, &port->dev_info); + if (ret != 0) + rte_exit(EXIT_FAILURE, + "rte_eth_dev_info_get() failed\n"); if (!(port->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)) port->dev_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; - if (!(port->dev_info.tx_offload_capa & - DEV_TX_OFFLOAD_MATCH_METADATA)) - port->dev_conf.txmode.offloads &= - ~DEV_TX_OFFLOAD_MATCH_METADATA; if (numa_support) { if (port_numa[pid] != NUMA_NO_CONFIG) port_per_socket[port_numa[pid]]++; @@ -1295,10 +1319,14 @@ void reconfig(portid_t new_port_id, unsigned socket_id) { struct rte_port *port; + int ret; /* Reconfiguration of Ethernet ports. */ port = &ports[new_port_id]; - rte_eth_dev_info_get(new_port_id, &port->dev_info); + + ret = eth_dev_info_get_print_err(new_port_id, &port->dev_info); + if (ret != 0) + return; /* set flag to initialize port/queue */ port->need_reconfig = 1; @@ -2039,6 +2067,63 @@ port_is_started(portid_t port_id) return 1; } +/* Configure the Rx and Tx hairpin queues for the selected port. */ +static int +setup_hairpin_queues(portid_t pi) +{ + queueid_t qi; + struct rte_eth_hairpin_conf hairpin_conf = { + .peer_count = 1, + }; + int i; + int diag; + struct rte_port *port = &ports[pi]; + + for (qi = nb_txq, i = 0; qi < nb_hairpinq + nb_txq; qi++) { + hairpin_conf.peers[0].port = pi; + hairpin_conf.peers[0].queue = i + nb_rxq; + diag = rte_eth_tx_hairpin_queue_setup + (pi, qi, nb_txd, &hairpin_conf); + i++; + 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 hairpin " + "queues\n", pi); + /* try to reconfigure queues next time */ + port->need_reconfig_queues = 1; + return -1; + } + for (qi = nb_rxq, i = 0; qi < nb_hairpinq + nb_rxq; qi++) { + hairpin_conf.peers[0].port = pi; + hairpin_conf.peers[0].queue = i + nb_txq; + diag = rte_eth_rx_hairpin_queue_setup + (pi, qi, nb_rxd, &hairpin_conf); + i++; + 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 hairpin " + "queues\n", pi); + /* try to reconfigure queues next time */ + port->need_reconfig_queues = 1; + return -1; + } + return 0; +} + int start_port(portid_t pid) { @@ -2047,6 +2132,7 @@ start_port(portid_t pid) queueid_t qi; struct rte_port *port; struct rte_ether_addr mac_addr; + struct rte_eth_hairpin_cap cap; if (port_id_is_invalid(pid, ENABLED_WARN)) return 0; @@ -2079,9 +2165,16 @@ start_port(portid_t pid) configure_rxtx_dump_callbacks(0); printf("Configuring Port %d (socket %u)\n", pi, port->socket_id); + if (nb_hairpinq > 0 && + rte_eth_dev_hairpin_capability_get(pi, &cap)) { + printf("Port %d doesn't support hairpin " + "queues\n", pi); + return -1; + } /* configure port */ - diag = rte_eth_dev_configure(pi, nb_rxq, nb_txq, - &(port->dev_conf)); + diag = rte_eth_dev_configure(pi, nb_rxq + nb_hairpinq, + nb_txq + nb_hairpinq, + &(port->dev_conf)); if (diag != 0) { if (rte_atomic16_cmpset(&(port->port_status), RTE_PORT_HANDLING, RTE_PORT_STOPPED) == 0) @@ -2174,8 +2267,20 @@ start_port(portid_t pid) port->need_reconfig_queues = 1; return -1; } + /* setup hairpin queues */ + if (setup_hairpin_queues(pi) != 0) + return -1; } configure_rxtx_dump_callbacks(verbose_level); + if (clear_ptypes) { + diag = rte_eth_dev_set_ptypes(pi, RTE_PTYPE_UNKNOWN, + NULL, 0); + if (diag < 0) + printf( + "Port %d: Failed to disable Ptype parsing\n", + pi); + } + /* start port */ if (rte_eth_dev_start(pi) < 0) { printf("Fail to start port %d\n", pi); @@ -2192,8 +2297,8 @@ start_port(portid_t pid) RTE_PORT_HANDLING, RTE_PORT_STARTED) == 0) printf("Port %d can not be set into started\n", pi); - rte_eth_macaddr_get(pi, &mac_addr); - printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, + if (eth_macaddr_get_print_err(pi, &mac_addr) == 0) + printf("Port %d: %02X:%02X:%02X:%02X:%02X:%02X\n", pi, mac_addr.addr_bytes[0], mac_addr.addr_bytes[1], mac_addr.addr_bytes[2], mac_addr.addr_bytes[3], mac_addr.addr_bytes[4], mac_addr.addr_bytes[5]); @@ -2344,6 +2449,12 @@ reset_port(portid_t pid) if (port_id_is_invalid(pid, ENABLED_WARN)) return; + if ((pid == (portid_t)RTE_PORT_ALL && !all_ports_stopped()) || + (pid != (portid_t)RTE_PORT_ALL && !port_is_stopped(pid))) { + printf("Can not reset port(s), please stop port(s) first.\n"); + return; + } + printf("Resetting ports...\n"); RTE_ETH_FOREACH_DEV(pi) { @@ -2416,13 +2527,17 @@ static void setup_attached_port(portid_t pi) { unsigned int socket_id; + int ret; socket_id = (unsigned)rte_eth_dev_socket_id(pi); /* if socket_id is invalid, set to the first available socket. */ if (check_socket_id(socket_id) < 0) socket_id = socket_ids[0]; reconfig(pi, socket_id); - rte_eth_promiscuous_enable(pi); + ret = rte_eth_promiscuous_enable(pi); + if (ret != 0) + printf("Error during enabling promiscuous mode for port %u: %s - ignore\n", + pi, rte_strerror(-ret)); ports_ids[nb_ports++] = pi; fwd_ports_ids[nb_fwd_ports++] = pi; @@ -2442,6 +2557,9 @@ detach_port_device(portid_t port_id) printf("Removing a device...\n"); + if (port_id_is_invalid(port_id, ENABLED_WARN)) + return; + dev = rte_eth_devices[port_id].device; if (dev == NULL) { printf("Device already removed\n"); @@ -2501,6 +2619,7 @@ detach_device(char *identifier) if (ports[port_id].port_status != RTE_PORT_CLOSED) { if (ports[port_id].port_status != RTE_PORT_STOPPED) { printf("Port %u not stopped\n", port_id); + rte_eth_iterator_cleanup(&iterator); return; } @@ -2604,6 +2723,7 @@ check_all_ports_link_status(uint32_t port_mask) portid_t portid; uint8_t count, all_ports_up, print_flag = 0; struct rte_eth_link link; + int ret; printf("Checking link statuses...\n"); fflush(stdout); @@ -2613,7 +2733,14 @@ check_all_ports_link_status(uint32_t port_mask) if ((port_mask & (1 << portid)) == 0) continue; memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); + ret = rte_eth_link_get_nowait(portid, &link); + if (ret < 0) { + all_ports_up = 0; + if (print_flag == 1) + printf("Port %u link get failed: %s\n", + portid, rte_strerror(-ret)); + continue; + } /* print link status if flag set */ if (print_flag == 1) { if (link.link_status) @@ -2927,11 +3054,16 @@ init_port_config(void) { portid_t pid; struct rte_port *port; + int ret; RTE_ETH_FOREACH_DEV(pid) { port = &ports[pid]; port->dev_conf.fdir_conf = fdir_conf; - rte_eth_dev_info_get(pid, &port->dev_info); + + ret = eth_dev_info_get_print_err(pid, &port->dev_info); + if (ret != 0) + return; + if (nb_rxq > 1) { port->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; port->dev_conf.rx_adv_conf.rss_conf.rss_hf = @@ -2950,7 +3082,9 @@ init_port_config(void) rxtx_port_config(port); - rte_eth_macaddr_get(pid, &port->eth_addr); + ret = eth_macaddr_get_print_err(pid, &port->eth_addr); + if (ret != 0) + return; map_port_queue_stats_mapping_registers(pid, port); #if defined RTE_LIBRTE_IXGBE_PMD && defined RTE_LIBRTE_IXGBE_BYPASS @@ -3106,7 +3240,10 @@ init_port_dcb_config(portid_t pid, retval = rte_eth_dev_configure(pid, nb_rxq, nb_rxq, &port_conf); if (retval < 0) return retval; - rte_eth_dev_info_get(pid, &rte_port->dev_info); + + retval = eth_dev_info_get_print_err(pid, &rte_port->dev_info); + if (retval != 0) + return retval; /* If dev_info.vmdq_pool_base is greater than 0, * the queue id of vmdq pools is started after pf queues. @@ -3150,7 +3287,10 @@ init_port_dcb_config(portid_t pid, for (i = 0; i < RTE_DIM(vlan_tags); i++) rx_vft_set(pid, vlan_tags[i], 1); - rte_eth_macaddr_get(pid, &rte_port->eth_addr); + retval = eth_macaddr_get_print_err(pid, &rte_port->eth_addr); + if (retval != 0) + return retval; + map_port_queue_stats_mapping_registers(pid, rte_port); rte_port->dcb_flag = 1; @@ -3212,7 +3352,8 @@ signal_handler(int signum) rte_pdump_uninit(); #endif #ifdef RTE_LIBRTE_LATENCY_STATS - rte_latencystats_uninit(); + if (latencystats_enabled != 0) + rte_latencystats_uninit(); #endif force_quit(); /* Set flag to indicate the force termination. */ @@ -3234,18 +3375,23 @@ main(int argc, char** argv) signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); - diag = rte_eal_init(argc, argv); - if (diag < 0) - rte_panic("Cannot init EAL\n"); - testpmd_logtype = rte_log_register("testpmd"); if (testpmd_logtype < 0) - rte_panic("Cannot register log type"); + rte_exit(EXIT_FAILURE, "Cannot register log type"); rte_log_set_level(testpmd_logtype, RTE_LOG_DEBUG); + diag = rte_eal_init(argc, argv); + if (diag < 0) + rte_exit(EXIT_FAILURE, "Cannot init EAL: %s\n", + rte_strerror(rte_errno)); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) + rte_exit(EXIT_FAILURE, + "Secondary process type not supported.\n"); + ret = register_eth_event_callback(); if (ret != 0) - rte_panic("Cannot register for ethdev events"); + rte_exit(EXIT_FAILURE, "Cannot register for ethdev events"); #ifdef RTE_LIBRTE_PDUMP /* initialize packet capture framework */ @@ -3266,8 +3412,8 @@ main(int argc, char** argv) set_def_fwd_config(); if (nb_lcores == 0) - rte_panic("Empty set of forwarding logical cores - check the " - "core mask supplied in the command parameters\n"); + rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n" + "Check the core mask argument\n"); /* Bitrate/latency stats disabled by default */ #ifdef RTE_LIBRTE_BITRATE @@ -3342,8 +3488,12 @@ main(int argc, char** argv) rte_exit(EXIT_FAILURE, "Start ports failed\n"); /* set all ports to promiscuous mode by default */ - RTE_ETH_FOREACH_DEV(port_id) - rte_eth_promiscuous_enable(port_id); + RTE_ETH_FOREACH_DEV(port_id) { + ret = rte_eth_promiscuous_enable(port_id); + if (ret != 0) + printf("Error during enabling promiscuous mode for port %u: %s - ignore\n", + port_id, rte_strerror(-ret)); + } /* Init metrics library */ rte_metrics_init(rte_socket_id());