[dpdk-dev] [PATCH 2/2] app/testpmd: provide TCP IPv4 GRO function in iofwd mode

Jiayu Hu jiayu.hu at intel.com
Wed Mar 22 10:32:17 CET 2017


This patch demonstrates the usage of the TCP IPv4 GRO library in testpmd.
Currently, only the iofwd mode supports this feature. By default, TCP
IPv4 GRO is turned off. The command, "gro tcp4 on", turns on this
feature; the command, "gro tcp4 off", turns off it.

Once the feature is turned on, all received packets are performed TCP
IPv4 GRO procedure before been forwarded.

Signed-off-by: Jiayu Hu <jiayu.hu at intel.com>
---
 app/test-pmd/cmdline.c | 48 ++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/config.c  | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/iofwd.c   |  7 ++++++
 app/test-pmd/testpmd.c | 10 +++++++++
 app/test-pmd/testpmd.h |  6 +++++
 5 files changed, 130 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 47f935d..618b9da 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_tcp.h>
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
@@ -396,6 +397,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"tso show (portid)"
 			"    Display the status of TCP Segmentation Offload.\n\n"
 
+			"gro tcp4 (on|off)"
+			"    Enable or disable TCP IPv4 Receive Offload.\n\n"
+
 			"set fwd (%s)\n"
 			"    Set packet forwarding mode.\n\n"
 
@@ -3784,6 +3788,49 @@ cmdline_parse_inst_t cmd_tunnel_tso_show = {
 	},
 };
 
+/* *** SET TCP IPv4 Receive Offload FOR RX PKTS *** */
+struct cmd_gro_result {
+	cmdline_fixed_string_t cmd_keyword;
+	cmdline_fixed_string_t protocol;
+	cmdline_fixed_string_t mode;
+};
+
+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;
+	if (strcmp(res->protocol, "tcp4") == 0)
+		setup_gro_tcp4(res->mode);
+	else
+		printf("unsupported GRO protocol\n");
+}
+
+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_protocol =
+	TOKEN_STRING_INITIALIZER(struct cmd_gro_result,
+			protocol, NULL);
+cmdline_parse_token_string_t cmd_gro_mode =
+	TOKEN_STRING_INITIALIZER(struct cmd_gro_result,
+			mode, NULL);
+
+cmdline_parse_inst_t cmd_set_gro = {
+	.f = cmd_set_gro_parsed,
+	.data = NULL,
+	.help_str = "gro tcp4 on|off",
+	.tokens = {
+		(void *)&cmd_gro_keyword,
+		(void *)&cmd_gro_protocol,
+		(void *)&cmd_gro_mode,
+		NULL,
+	},
+};
+
 /* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
 struct cmd_set_flush_rx {
 	cmdline_fixed_string_t set;
@@ -12464,6 +12511,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 80491fc..b4144a3 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -97,6 +97,7 @@
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif
+#include <rte_gro_tcp.h>
 
 #include "testpmd.h"
 
@@ -2415,6 +2416,64 @@ set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs)
 	tx_pkt_nb_segs = (uint8_t) nb_segs;
 }
 
+void
+setup_gro_tcp4(const char *mode)
+{
+	lcoreid_t lc_id;
+	streamid_t sm_id;
+	uint64_t nb_entries = 64;	/* lookup table entry number */
+
+	if (strcmp(mode, "on") == 0) {
+		if (test_done == 0) {
+			printf("Before enable TCP IPv4 GRO,"
+					" please stop forwarding first\n");
+			return;
+		}
+		if (enable_gro_tcp4 == 1) {
+			printf("GRO TCP IPv4 has been turned on\n");
+			return;
+		}
+		for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
+			char name[20];
+
+			snprintf(name, sizeof(name), "GRO_TCP4_%u", lc_id);
+			if (gro_tcp4_tbls[lc_id])
+				rte_hash_free(gro_tcp4_tbls[lc_id]);
+
+			gro_tcp4_tbls[lc_id] = rte_gro_tcp4_tbl_create(
+					name,
+					nb_entries,
+					rte_lcore_to_socket_id
+					(fwd_lcores_cpuids[lc_id]));
+			if (gro_tcp4_tbls[lc_id] == NULL) {
+				enable_gro_tcp4 = 0;
+				return;
+			}
+			for (sm_id = fwd_lcores[lc_id]->stream_idx; sm_id <
+					fwd_lcores[lc_id]->stream_idx +
+					fwd_lcores[lc_id]->stream_nb; sm_id++) {
+				fwd_streams[sm_id]->tbl_idx = lc_id;
+			}
+		}
+		enable_gro_tcp4 = 1;
+	} else if (strcmp(mode, "off") == 0) {
+		if (test_done == 0) {
+			printf("Before disable TCP IPv4 GRO,"
+					" please stop forwarding first\n");
+			return;
+		}
+		if (enable_gro_tcp4 == 0) {
+			printf("GRO TCP IPv4 has been turned off\n");
+			return;
+		}
+		for (lc_id = 0; lc_id < cur_fwd_config.nb_fwd_lcores; lc_id++) {
+			rte_hash_free(gro_tcp4_tbls[lc_id]);
+			gro_tcp4_tbls[lc_id] = NULL;
+		}
+		enable_gro_tcp4 = 0;
+	}
+}
+
 char*
 list_pkt_forwarding_modes(void)
 {
diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c
index 15cb4a2..ec05d6f 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_tcp.h>
 
 #include "testpmd.h"
 
@@ -99,6 +100,12 @@ pkt_burst_io_forward(struct fwd_stream *fs)
 			pkts_burst, nb_pkt_per_burst);
 	if (unlikely(nb_rx == 0))
 		return;
+	if (enable_gro_tcp4) {
+		nb_rx = rte_gro_tcp4_reassemble_burst(
+				gro_tcp4_tbls[fs->tbl_idx],
+				pkts_burst,
+				nb_rx);
+	}
 	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 e04e215..caf8a61 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -273,6 +273,16 @@ uint32_t bypass_timeout = RTE_BYPASS_TMT_OFF;
 #endif
 
 /*
+ * TCP IPv4 lookup tables. Each lcore has a lookup table.
+ */
+struct rte_hash *gro_tcp4_tbls[RTE_MAX_LCORE];
+
+/*
+ * TCP IPv4 GRO enable/disable flag.
+ */
+uint8_t enable_gro_tcp4 = 0;	/* turn off by default */
+
+/*
  * Ethernet device configuration.
  */
 struct rte_eth_rxmode rx_mode = {
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 8cf2860..bfd1e52 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -109,6 +109,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 */
@@ -420,6 +422,9 @@ 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. */
 
+extern struct rte_hash *gro_tcp4_tbls[RTE_MAX_LCORE];
+extern uint8_t enable_gro_tcp4;
+
 static inline unsigned int
 lcore_num(void)
 {
@@ -616,6 +621,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_tcp4(const char *mode);
 
 /* 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



More information about the dev mailing list