This patch demonstrates the usage of GRO library in testpmd. By default, GRO is turned off. Command, "gro on (port_id)", turns on GRO for the given port; command, "gro off (port_id)", turns off GRO for the given port. Currently, GRO only supports to process TCP/IPv4 packets and works in IO forward mode. Besides, only GRO lightweight mode is enabled.
Signed-off-by: Jiayu Hu <jiayu...@intel.com> --- app/test-pmd/cmdline.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ app/test-pmd/config.c | 29 +++++++++++++++++++++++++++++ app/test-pmd/iofwd.c | 6 ++++++ app/test-pmd/testpmd.c | 3 +++ app/test-pmd/testpmd.h | 11 +++++++++++ 5 files changed, 94 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 0afac68..24cb4ff 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -76,6 +76,7 @@ #include <rte_devargs.h> #include <rte_eth_ctrl.h> #include <rte_flow.h> +#include <rte_gro.h> #include <cmdline_rdline.h> #include <cmdline_parse.h> @@ -420,6 +421,9 @@ static void cmd_help_long_parsed(void *parsed_result, "tso show (portid)" " Display the status of TCP Segmentation Offload.\n\n" + "gro (on|off) (port_id)" + " Enable or disable Generic Receive Offload.\n\n" + "set fwd (%s)\n" " Set packet forwarding mode.\n\n" @@ -3825,6 +3829,46 @@ cmdline_parse_inst_t cmd_tunnel_tso_show = { }, }; +/* *** SET GRO FOR A PORT *** */ +struct cmd_gro_result { + cmdline_fixed_string_t cmd_keyword; + cmdline_fixed_string_t mode; + uint8_t port_id; +}; + +static void +cmd_set_gro_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_gro_result *res; + + res = parsed_result; + setup_gro(res->mode, res->port_id); +} + +cmdline_parse_token_string_t cmd_gro_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_gro_result, + cmd_keyword, "gro"); +cmdline_parse_token_string_t cmd_gro_mode = + TOKEN_STRING_INITIALIZER(struct cmd_gro_result, + mode, "on#off"); +cmdline_parse_token_num_t cmd_gro_pid = + TOKEN_NUM_INITIALIZER(struct cmd_gro_result, + port_id, UINT8); + +cmdline_parse_inst_t cmd_set_gro = { + .f = cmd_set_gro_parsed, + .data = NULL, + .help_str = "gro (on|off) (port_id)", + .tokens = { + (void *)&cmd_gro_keyword, + (void *)&cmd_gro_mode, + (void *)&cmd_gro_pid, + NULL, + }, +}; + /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */ struct cmd_set_flush_rx { cmdline_fixed_string_t set; @@ -13629,6 +13673,7 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_tso_show, (cmdline_parse_inst_t *)&cmd_tunnel_tso_set, (cmdline_parse_inst_t *)&cmd_tunnel_tso_show, + (cmdline_parse_inst_t *)&cmd_set_gro, (cmdline_parse_inst_t *)&cmd_link_flow_control_set, (cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx, (cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx, diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 14be759..e8a665f 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -68,6 +68,7 @@ #ifdef RTE_LIBRTE_IXGBE_PMD #include <rte_pmd_ixgbe.h> #endif +#include <rte_gro.h> #include "testpmd.h" @@ -2393,6 +2394,34 @@ set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs) tx_pkt_nb_segs = (uint8_t) nb_segs; } +void +setup_gro(const char *mode, uint8_t port_id) +{ + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("invalid port id %u\n", port_id); + return; + } + if (strcmp(mode, "on") == 0) { + if (test_done == 0) { + printf("before enable GRO," + " please stop forwarding first\n"); + return; + } + gro_ports[port_id].enable = 1; + gro_ports[port_id].param.max_flow_num = 4; + gro_ports[port_id].param.max_item_per_flow = 32; + gro_ports[port_id].param.desired_gro_types = GRO_TCP_IPV4; + gro_ports[port_id].param.max_packet_size = UINT16_MAX; + } else if (strcmp(mode, "off") == 0) { + if (test_done == 0) { + printf("before disable GRO," + " please stop forwarding first\n"); + return; + } + gro_ports[port_id].enable = 0; + } +} + char* list_pkt_forwarding_modes(void) { diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c index 15cb4a2..d9ec528 100644 --- a/app/test-pmd/iofwd.c +++ b/app/test-pmd/iofwd.c @@ -65,6 +65,7 @@ #include <rte_ethdev.h> #include <rte_string_fns.h> #include <rte_flow.h> +#include <rte_gro.h> #include "testpmd.h" @@ -99,6 +100,11 @@ pkt_burst_io_forward(struct fwd_stream *fs) pkts_burst, nb_pkt_per_burst); if (unlikely(nb_rx == 0)) return; + if (unlikely(gro_ports[fs->rx_port].enable)) { + nb_rx = rte_gro_reassemble_burst(pkts_burst, + nb_rx, + gro_ports[fs->rx_port].param); + } fs->rx_packets += nb_rx; #ifdef RTE_TEST_PMD_RECORD_BURST_STATS diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index d1041af..8d7a6a6 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -87,6 +87,7 @@ #ifdef RTE_LIBRTE_LATENCY_STATS #include <rte_latencystats.h> #endif +#include <rte_gro.h> #include "testpmd.h" @@ -375,6 +376,8 @@ lcoreid_t bitrate_lcore_id; uint8_t bitrate_enabled; #endif +struct gro_status gro_ports[RTE_MAX_ETHPORTS]; + /* 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); diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index e6c43ba..4c6ed03 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -34,6 +34,8 @@ #ifndef _TESTPMD_H_ #define _TESTPMD_H_ +#include <rte_gro.h> + #define RTE_PORT_ALL (~(portid_t)0x0) #define RTE_TEST_RX_DESC_MAX 2048 @@ -109,6 +111,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 */ + uint16_t tbl_idx; /**< TCP IPv4 GRO lookup tale index */ + unsigned int retry_enabled; /* "read-write" results */ @@ -428,6 +432,12 @@ extern struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS]; extern uint32_t burst_tx_delay_time; /**< Burst tx delay time(us) for mac-retry. */ extern uint32_t burst_tx_retry_num; /**< Burst tx retry number for mac-retry. */ +struct gro_status { + struct rte_gro_param param; + uint8_t enable; +}; +extern struct gro_status gro_ports[RTE_MAX_ETHPORTS]; + static inline unsigned int lcore_num(void) { @@ -625,6 +635,7 @@ void get_2tuple_filter(uint8_t port_id, uint16_t index); void get_5tuple_filter(uint8_t port_id, uint16_t index); int rx_queue_id_is_invalid(queueid_t rxq_id); int tx_queue_id_is_invalid(queueid_t txq_id); +void setup_gro(const char *mode, uint8_t port_id); /* Functions to manage the set of filtered Multicast MAC addresses */ void mcast_addr_add(uint8_t port_id, struct ether_addr *mc_addr); -- 2.7.4