From: Zhihong Wang Date: Tue, 14 Jun 2016 23:08:02 +0000 (-0400) Subject: app/testpmd: add retry option X-Git-Tag: spdx-start~6731 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=bf56fce1fb45;p=dpdk.git app/testpmd: add retry option This patch adds retry option in testpmd to prevent most packet losses. It can be enabled by "set fwd retry". All modes except rxonly support this option. Adding retry mechanism expands test case coverage to support scenarios where packet loss affects test results. Signed-off-by: Zhihong Wang Acked-by: Pablo de Lara --- diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index 40039a1d6d..2a0b5a5d5c 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -50,7 +50,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline.c SRCS-y += config.c SRCS-y += iofwd.c SRCS-y += macfwd.c -SRCS-y += macfwd-retry.c SRCS-y += macswap.c SRCS-y += flowgen.c SRCS-y += rxonly.c diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 73a5a4788c..8a41ece351 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -246,8 +246,8 @@ static void cmd_help_long_parsed(void *parsed_result, " Set number of packets per burst.\n\n" "set burst tx delay (microseconds) retry (num)\n" - " Set the transmit delay time and number of retries" - " in mac_retry forwarding mode.\n\n" + " Set the transmit delay time and number of retries," + " effective when retry is enabled.\n\n" "set txpkts (x[,y]*)\n" " Set the length of each segment of TXONLY" @@ -4568,6 +4568,7 @@ static void cmd_set_fwd_mode_parsed(void *parsed_result, { struct cmd_set_fwd_mode_result *res = parsed_result; + retry_enabled = 0; set_pkt_forwarding_mode(res->mode); } @@ -4613,6 +4614,74 @@ static void cmd_set_fwd_mode_init(void) token_struct->string_data.str = token; } +/* *** SET RETRY FORWARDING MODE *** */ +struct cmd_set_fwd_retry_mode_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t fwd; + cmdline_fixed_string_t mode; + cmdline_fixed_string_t retry; +}; + +static void cmd_set_fwd_retry_mode_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_fwd_retry_mode_result *res = parsed_result; + + retry_enabled = 1; + set_pkt_forwarding_mode(res->mode); +} + +cmdline_parse_token_string_t cmd_setfwd_retry_set = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + set, "set"); +cmdline_parse_token_string_t cmd_setfwd_retry_fwd = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + fwd, "fwd"); +cmdline_parse_token_string_t cmd_setfwd_retry_mode = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + mode, + "" /* defined at init */); +cmdline_parse_token_string_t cmd_setfwd_retry_retry = + TOKEN_STRING_INITIALIZER(struct cmd_set_fwd_retry_mode_result, + retry, "retry"); + +cmdline_parse_inst_t cmd_set_fwd_retry_mode = { + .f = cmd_set_fwd_retry_mode_parsed, + .data = NULL, + .help_str = NULL, /* defined at init */ + .tokens = { + (void *)&cmd_setfwd_retry_set, + (void *)&cmd_setfwd_retry_fwd, + (void *)&cmd_setfwd_retry_mode, + (void *)&cmd_setfwd_retry_retry, + NULL, + }, +}; + +static void cmd_set_fwd_retry_mode_init(void) +{ + char *modes, *c; + static char token[128]; + static char help[256]; + cmdline_parse_token_string_t *token_struct; + + modes = list_pkt_forwarding_retry_modes(); + snprintf(help, sizeof(help), "set fwd %s retry - " + "set packet forwarding mode with retry", modes); + cmd_set_fwd_retry_mode.help_str = help; + + /* string token separator is # */ + for (c = token; *modes != '\0'; modes++) + if (*modes == '|') + *c++ = '#'; + else + *c++ = *modes; + token_struct = (cmdline_parse_token_string_t *) + cmd_set_fwd_retry_mode.tokens[2]; + token_struct->string_data.str = token; +} + /* *** SET BURST TX DELAY TIME RETRY NUMBER *** */ struct cmd_set_burst_tx_retry_result { cmdline_fixed_string_t set; @@ -10493,6 +10562,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_set_fwd_list, (cmdline_parse_inst_t *)&cmd_set_fwd_mask, (cmdline_parse_inst_t *)&cmd_set_fwd_mode, + (cmdline_parse_inst_t *)&cmd_set_fwd_retry_mode, (cmdline_parse_inst_t *)&cmd_set_burst_tx_retry, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_one, (cmdline_parse_inst_t *)&cmd_set_promisc_mode_all, @@ -10632,6 +10702,7 @@ prompt(void) { /* initialize non-constant commands */ cmd_set_fwd_mode_init(); + cmd_set_fwd_retry_mode_init(); testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); if (testpmd_cl == NULL) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 24eac3cc63..eb5514d18d 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -893,8 +893,9 @@ fwd_lcores_config_display(void) void rxtx_config_display(void) { - printf(" %s packet forwarding - CRC stripping %s - " + printf(" %s packet forwarding%s - CRC stripping %s - " "packets/burst=%d\n", cur_fwd_eng->fwd_mode_name, + retry_enabled == 0 ? "" : " with retry", rx_mode.hw_strip_crc ? "enabled" : "disabled", nb_pkt_per_burst); @@ -1131,6 +1132,7 @@ simple_fwd_config_setup(void) fwd_streams[i]->tx_port = fwd_ports_ids[j]; fwd_streams[i]->tx_queue = 0; fwd_streams[i]->peer_addr = j; + fwd_streams[i]->retry_enabled = retry_enabled; if (port_topology == PORT_TOPOLOGY_PAIRED) { fwd_streams[j]->rx_port = fwd_ports_ids[j]; @@ -1138,6 +1140,7 @@ simple_fwd_config_setup(void) fwd_streams[j]->tx_port = fwd_ports_ids[i]; fwd_streams[j]->tx_queue = 0; fwd_streams[j]->peer_addr = i; + fwd_streams[j]->retry_enabled = retry_enabled; } } } @@ -1206,6 +1209,7 @@ rss_fwd_config_setup(void) fs->tx_port = fwd_ports_ids[txp]; fs->tx_queue = rxq; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; rxq = (queueid_t) (rxq + 1); if (rxq < nb_q) continue; @@ -1280,6 +1284,7 @@ dcb_fwd_config_setup(void) fs->tx_port = fwd_ports_ids[txp]; fs->tx_queue = txq + j % nb_tx_queue; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; } fwd_lcores[lc_id]->stream_nb += rxp_dcb_info.tc_queue.tc_rxq[i][tc].nb_queue; @@ -1350,6 +1355,7 @@ icmp_echo_config_setup(void) fs->tx_port = fs->rx_port; fs->tx_queue = rxq; fs->peer_addr = fs->tx_port; + fs->retry_enabled = retry_enabled; if (verbose_level > 0) printf(" stream=%d port=%d rxq=%d txq=%d\n", sm_id, fs->rx_port, fs->rx_queue, @@ -1388,14 +1394,15 @@ pkt_fwd_config_display(struct fwd_config *cfg) lcoreid_t lc_id; streamid_t sm_id; - printf("%s packet forwarding - ports=%d - cores=%d - streams=%d - " + printf("%s packet forwarding%s - ports=%d - cores=%d - streams=%d - " "NUMA support %s, MP over anonymous pages %s\n", cfg->fwd_eng->fwd_mode_name, + retry_enabled == 0 ? "" : " with retry", cfg->nb_fwd_ports, cfg->nb_fwd_lcores, cfg->nb_fwd_streams, numa_support == 1 ? "enabled" : "disabled", mp_anon != 0 ? "enabled" : "disabled"); - if (strcmp(cfg->fwd_eng->fwd_mode_name, "mac_retry") == 0) + if (retry_enabled) printf("TX retry num: %u, delay between TX retries: %uus\n", burst_tx_retry_num, burst_tx_delay_time); for (lc_id = 0; lc_id < cfg->nb_fwd_lcores; lc_id++) { @@ -1692,6 +1699,31 @@ list_pkt_forwarding_modes(void) return fwd_modes; } +char* +list_pkt_forwarding_retry_modes(void) +{ + static char fwd_modes[128] = ""; + const char *separator = "|"; + struct fwd_engine *fwd_eng; + unsigned i = 0; + + if (strlen(fwd_modes) == 0) { + while ((fwd_eng = fwd_engines[i++]) != NULL) { + if (fwd_eng == &rx_only_engine) + continue; + strncat(fwd_modes, fwd_eng->fwd_mode_name, + sizeof(fwd_modes) - + strlen(fwd_modes) - 1); + strncat(fwd_modes, separator, + sizeof(fwd_modes) - + strlen(fwd_modes) - 1); + } + fwd_modes[strlen(fwd_modes) - strlen(separator)] = '\0'; + } + + return fwd_modes; +} + void set_pkt_forwarding_mode(const char *fwd_mode_name) { @@ -1701,8 +1733,9 @@ set_pkt_forwarding_mode(const char *fwd_mode_name) i = 0; while ((fwd_eng = fwd_engines[i]) != NULL) { if (! strcmp(fwd_eng->fwd_mode_name, fwd_mode_name)) { - printf("Set %s packet forwarding mode\n", - fwd_mode_name); + printf("Set %s packet forwarding mode%s\n", + fwd_mode_name, + retry_enabled == 0 ? "" : " with retry"); cur_fwd_eng = fwd_eng; return; } diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 1d6cda1508..ac4bd8f472 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -643,6 +643,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint16_t i; uint64_t ol_flags; uint16_t testpmd_ol_flags; + uint32_t retry; uint32_t rx_bad_ip_csum; uint32_t rx_bad_l4_csum; struct testpmd_offload_info info; @@ -848,6 +849,17 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) } } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; fs->rx_bad_ip_csum += rx_bad_ip_csum; fs->rx_bad_l4_csum += rx_bad_l4_csum; diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c index 18b754bf36..a6abe91e5d 100644 --- a/app/test-pmd/flowgen.c +++ b/app/test-pmd/flowgen.c @@ -131,6 +131,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs) uint16_t nb_tx; uint16_t nb_pkt; uint16_t i; + uint32_t retry; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; uint64_t end_tsc; @@ -207,6 +208,17 @@ pkt_burst_flow_gen(struct fwd_stream *fs) } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c index ed6e9249d7..be308c9f4c 100644 --- a/app/test-pmd/icmpecho.c +++ b/app/test-pmd/icmpecho.c @@ -311,6 +311,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) struct ipv4_hdr *ip_h; struct icmp_hdr *icmp_h; struct ether_addr eth_addr; + uint32_t retry; uint32_t ip_addr; uint16_t nb_rx; uint16_t nb_tx; @@ -518,6 +519,20 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) if (nb_replies > 0) { nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_replies); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_replies) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_replies && + retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, + fs->tx_queue, + &pkts_burst[nb_tx], + nb_replies - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c index 8840d86805..7b6033a57c 100644 --- a/app/test-pmd/iofwd.c +++ b/app/test-pmd/iofwd.c @@ -80,6 +80,8 @@ pkt_burst_io_forward(struct fwd_stream *fs) struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; uint16_t nb_rx; uint16_t nb_tx; + uint32_t retry; + #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; uint64_t end_tsc; @@ -93,16 +95,28 @@ pkt_burst_io_forward(struct fwd_stream *fs) /* * Receive a burst of packets and forward them. */ - nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, - nb_pkt_per_burst); + nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, + pkts_burst, nb_pkt_per_burst); if (unlikely(nb_rx == 0)) return; + fs->rx_packets += nb_rx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->rx_burst_stats.pkt_burst_spread[nb_rx]++; #endif - fs->rx_packets += nb_rx; - nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/macfwd-retry.c b/app/test-pmd/macfwd-retry.c deleted file mode 100644 index d8cd069c77..0000000000 --- a/app/test-pmd/macfwd-retry.c +++ /dev/null @@ -1,167 +0,0 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "testpmd.h" - -#define BURST_TX_WAIT_US 10 -#define BURST_TX_RETRIES 5 - -/* - * Global variables that control number of retires and - * timeout (in us) between retires. - */ -uint32_t burst_tx_delay_time = BURST_TX_WAIT_US; -uint32_t burst_tx_retry_num = BURST_TX_RETRIES; - -/* - * Forwarding of packets in MAC mode with a wait and retry on TX to reduce packet loss. - * Change the source and the destination Ethernet addressed of packets - * before forwarding them. - */ -static void -pkt_burst_mac_retry_forward(struct fwd_stream *fs) -{ - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_mbuf *mb; - struct ether_hdr *eth_hdr; - uint32_t retry; - uint16_t nb_rx; - uint16_t nb_tx; - uint16_t i; -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - uint64_t start_tsc; - uint64_t end_tsc; - uint64_t core_cycles; -#endif - -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - start_tsc = rte_rdtsc(); -#endif - - /* - * Receive a burst of packets and forward them. - */ - nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, - nb_pkt_per_burst); - if (unlikely(nb_rx == 0)) - return; - -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->rx_burst_stats.pkt_burst_spread[nb_rx]++; -#endif - fs->rx_packets += nb_rx; - for (i = 0; i < nb_rx; i++) { - if (likely(i < nb_rx - 1)) - rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1], - void *)); - mb = pkts_burst[i]; - eth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *); - ether_addr_copy(&peer_eth_addrs[fs->peer_addr], - ð_hdr->d_addr); - ether_addr_copy(&ports[fs->tx_port].eth_addr, - ð_hdr->s_addr); - } - nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); - - /* - * If not all packets have been TX'd then wait and retry. - */ - if (unlikely(nb_tx < nb_rx)) { - for (retry = 0; retry < burst_tx_retry_num; retry++) { - rte_delay_us(burst_tx_delay_time); - nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, - &pkts_burst[nb_tx], nb_rx - nb_tx); - if (nb_tx == nb_rx) - break; - } - } - - fs->tx_packets += nb_tx; -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; -#endif - if (unlikely(nb_tx < nb_rx)) { - fs->fwd_dropped += (nb_rx - nb_tx); - do { - rte_pktmbuf_free(pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); - } -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - end_tsc = rte_rdtsc(); - core_cycles = (end_tsc - start_tsc); - fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles); -#endif -} - -struct fwd_engine mac_retry_fwd_engine = { - .fwd_mode_name = "mac_retry", - .port_fwd_begin = NULL, - .port_fwd_end = NULL, - .packet_fwd = pkt_burst_mac_retry_forward, -}; diff --git a/app/test-pmd/macfwd.c b/app/test-pmd/macfwd.c index 07a399afdb..5d1c1617b3 100644 --- a/app/test-pmd/macfwd.c +++ b/app/test-pmd/macfwd.c @@ -81,6 +81,7 @@ pkt_burst_mac_forward(struct fwd_stream *fs) struct rte_port *txp; struct rte_mbuf *mb; struct ether_hdr *eth_hdr; + uint32_t retry; uint16_t nb_rx; uint16_t nb_tx; uint16_t i; @@ -129,6 +130,18 @@ pkt_burst_mac_forward(struct fwd_stream *fs) mb->vlan_tci_outer = txp->tx_vlan_id_outer; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } + fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/macswap.c b/app/test-pmd/macswap.c index c10f4b54b4..4b0dbeb507 100644 --- a/app/test-pmd/macswap.c +++ b/app/test-pmd/macswap.c @@ -84,6 +84,7 @@ pkt_burst_mac_swap(struct fwd_stream *fs) uint16_t nb_rx; uint16_t nb_tx; uint16_t i; + uint32_t retry; uint64_t ol_flags = 0; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES uint64_t start_tsc; @@ -131,6 +132,17 @@ pkt_burst_mac_swap(struct fwd_stream *fs) mb->vlan_tci_outer = txp->tx_vlan_id_outer; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_rx - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index 60be4164f8..89458547d4 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -144,7 +144,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 +158,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 diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index df66d8dfb1..2b281cc467 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -103,6 +103,8 @@ struct fwd_stream { queueid_t tx_queue; /**< TX queue to send forwarded packets */ streamid_t peer_addr; /**< index of peer ethernet address of packets */ + unsigned int retry_enabled; + /* "read-write" results */ unsigned int rx_packets; /**< received packets */ unsigned int tx_packets; /**< received packets transmitted */ @@ -220,9 +222,14 @@ struct fwd_engine { packet_fwd_t packet_fwd; /**< Mandatory. */ }; +#define BURST_TX_WAIT_US 1 +#define BURST_TX_RETRIES 64 + +extern uint32_t burst_tx_delay_time; +extern uint32_t burst_tx_retry_num; + extern struct fwd_engine io_fwd_engine; extern struct fwd_engine mac_fwd_engine; -extern struct fwd_engine mac_retry_fwd_engine; extern struct fwd_engine mac_swap_engine; extern struct fwd_engine flow_gen_engine; extern struct fwd_engine rx_only_engine; @@ -380,6 +387,7 @@ extern int8_t tx_wthresh; extern struct fwd_config cur_fwd_config; extern struct fwd_engine *cur_fwd_eng; +extern uint32_t retry_enabled; extern struct fwd_lcore **fwd_lcores; extern struct fwd_stream **fwd_streams; @@ -524,6 +532,7 @@ void show_tx_pkt_segments(void); void set_tx_pkt_split(const char *name); void set_nb_pkt_per_burst(uint16_t pkt_burst); char *list_pkt_forwarding_modes(void); +char *list_pkt_forwarding_retry_modes(void); void set_pkt_forwarding_mode(const char *fwd_mode); void start_packet_forwarding(int with_tx_first); void stop_packet_forwarding(void); diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c index 0ac2a08092..11fd681da1 100644 --- a/app/test-pmd/txonly.c +++ b/app/test-pmd/txonly.c @@ -193,6 +193,7 @@ pkt_burst_transmit(struct fwd_stream *fs) uint16_t nb_tx; uint16_t nb_pkt; uint16_t vlan_tci, vlan_tci_outer; + uint32_t retry; uint64_t ol_flags = 0; uint8_t i; #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES @@ -273,6 +274,17 @@ pkt_burst_transmit(struct fwd_stream *fs) pkts_burst[nb_pkt] = pkt; } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt); + /* + * Retry if necessary + */ + if (unlikely(nb_tx < nb_pkt) && fs->retry_enabled) { + retry = 0; + while (nb_tx < nb_pkt && retry++ < burst_tx_retry_num) { + rte_delay_us(burst_tx_delay_time); + nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, + &pkts_burst[nb_tx], nb_pkt - nb_tx); + } + } fs->tx_packets += nb_tx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst index 8fb0651505..7712bd2404 100644 --- a/doc/guides/testpmd_app_ug/run_app.rst +++ b/doc/guides/testpmd_app_ug/run_app.rst @@ -333,7 +333,6 @@ The commandline options are: io (the default) mac - mac_retry mac_swap flowgen rxonly diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 22bb10809f..d812989971 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -249,8 +249,10 @@ set fwd Set the packet forwarding mode:: - testpmd> set fwd (io|mac|mac_retry|macswap|flowgen| \ - rxonly|txonly|csum|icmpecho) + testpmd> set fwd (io|mac|macswap|flowgen| \ + rxonly|txonly|csum|icmpecho) (""|retry) + +``retry`` can be specified for forwarding engines except ``rx_only``. The available information categories are: @@ -260,8 +262,6 @@ The available information categories are: * ``mac``: Changes the source and the destination Ethernet addresses of packets before forwarding them. -* ``mac_retry``: Same as "mac" forwarding mode, but includes retries if the destination queue is full. - * ``macswap``: MAC swap forwarding mode. Swaps the source and the destination Ethernet addresses of packets before forwarding them. @@ -392,9 +392,9 @@ Set number of packets per burst:: This is equivalent to the ``--burst command-line`` option. -In ``mac_retry`` forwarding mode, the transmit delay time and number of retries can also be set:: +When retry is enabled, the transmit delay time and number of retries can also be set:: - testpmd> set burst tx delay (micrseconds) retry (num) + testpmd> set burst tx delay (microseconds) retry (num) set txpkts ~~~~~~~~~~