From: Olivier Matz <olivier.matz@6wind.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 12/17] mbuf: generic support of TCP segmentation offload
Date: Mon, 19 May 2014 15:56:24 +0200 [thread overview]
Message-ID: <1400507789-18453-13-git-send-email-olivier.matz@6wind.com> (raw)
In-Reply-To: <1400507789-18453-1-git-send-email-olivier.matz@6wind.com>
Implement the generic part of TCP segmentation offload:
- rte_mbuf modifications
- testpmd for validation
To delegate the TCP segmentation to the hardware, the user has to:
- set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies
PKT_TX_IP_CKSUM and PKT_TX_TCP_CKSUM)
- fill the mbuf->hw_offload information: l2_len, l3_len, l4_len, mss
- calculate the pseudo header checksum and set it in the TCP header,
as required when doing hardware TCP checksum offload
- set the IP checksum to 0
The API is inspired from ixgbe hardware (the next commit adds the
support for ixgbe), but it seems generic enough to be used for other
hw/drivers in the future.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
app/test-pmd/cmdline.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
app/test-pmd/config.c | 8 ++++++++
app/test-pmd/csumonly.c | 16 ++++++++++++++++
app/test-pmd/testpmd.h | 2 ++
lib/librte_mbuf/rte_mbuf.h | 17 +++++++++++++++--
5 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 8f155e9..c686901 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2298,6 +2298,50 @@ cmdline_parse_inst_t cmd_tx_cksum_set = {
},
};
+/* *** ENABLE HARDWARE SEGMENTATION IN TX PACKETS *** */
+struct cmd_tso_set_result {
+ cmdline_fixed_string_t tso;
+ cmdline_fixed_string_t set;
+ uint16_t mss;
+ uint8_t port_id;
+};
+
+static void
+cmd_tso_set_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_tso_set_result *res = parsed_result;
+ tso_set(res->port_id, res->mss);
+}
+
+cmdline_parse_token_string_t cmd_tso_set_tso =
+ TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+ tso, "tso");
+cmdline_parse_token_string_t cmd_tso_set_set =
+ TOKEN_STRING_INITIALIZER(struct cmd_tso_set_result,
+ set, "set");
+cmdline_parse_token_num_t cmd_tso_set_mss =
+ TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+ mss, UINT16);
+cmdline_parse_token_num_t cmd_tso_set_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_tso_set_result,
+ port_id, UINT8);
+
+cmdline_parse_inst_t cmd_tso_set = {
+ .f = cmd_tso_set_parsed,
+ .data = NULL,
+ .help_str = "Enable hardware segmentation (set MSS to 0 to disable): "
+ "tso set <MSS> <PORT>",
+ .tokens = {
+ (void *)&cmd_tso_set_tso,
+ (void *)&cmd_tso_set_set,
+ (void *)&cmd_tso_set_mss,
+ (void *)&cmd_tso_set_portid,
+ NULL,
+ },
+};
+
/* *** ENABLE/DISABLE FLUSH ON RX STREAMS *** */
struct cmd_set_flush_rx {
cmdline_fixed_string_t set;
@@ -5197,6 +5241,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_tx_vlan_set,
(cmdline_parse_inst_t *)&cmd_tx_vlan_reset,
(cmdline_parse_inst_t *)&cmd_tx_cksum_set,
+ (cmdline_parse_inst_t *)&cmd_tso_set,
(cmdline_parse_inst_t *)&cmd_link_flow_control_set,
(cmdline_parse_inst_t *)&cmd_priority_flow_control_set,
(cmdline_parse_inst_t *)&cmd_config_dcb,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 018a278..184efdb 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1545,6 +1545,14 @@ tx_cksum_set(portid_t port_id, uint32_t ol_flags)
}
void
+tso_set(portid_t port_id, uint16_t mss)
+{
+ if (port_id_is_invalid(port_id))
+ return;
+ ports[port_id].tx_mss = mss;
+}
+
+void
fdir_add_signature_filter(portid_t port_id, uint8_t queue_id,
struct rte_fdir_filter *fdir_filter)
{
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index e93d75f..9983618 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -220,10 +220,12 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
uint32_t ol_flags;
uint32_t pkt_ol_flags;
uint32_t tx_ol_flags;
+ uint16_t tx_mss;
uint16_t l4_proto;
uint16_t eth_type;
uint8_t l2_len;
uint8_t l3_len;
+ uint8_t l4_len;
uint32_t rx_bad_ip_csum;
uint32_t rx_bad_l4_csum;
@@ -255,6 +257,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
txp = &ports[fs->tx_port];
tx_ol_flags = txp->tx_ol_flags;
+ tx_mss = txp->tx_mss;
for (i = 0; i < nb_rx; i++) {
@@ -272,6 +275,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
((uintptr_t)ð_hdr->ether_type +
sizeof(struct vlan_hdr)));
}
+ l4_len = 0;
/* Update the L3/L4 checksum error packet count */
rx_bad_ip_csum += ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);
@@ -347,6 +351,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
tcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
(uint16_t*)tcp_hdr);
}
+
+ if (tx_mss != 0) {
+ ol_flags |= PKT_TX_TCP_SEG;
+ l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+ }
}
else if (l4_proto == IPPROTO_SCTP) {
sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
@@ -404,6 +413,11 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
tcp_hdr->cksum = get_ipv6_udptcp_checksum(ipv6_hdr,
(uint16_t*)tcp_hdr);
}
+
+ if (tx_mss != 0) {
+ ol_flags |= PKT_TX_TCP_SEG;
+ l4_len = (tcp_hdr->data_off & 0xf0) >> 2;
+ }
}
else if (l4_proto == IPPROTO_SCTP) {
sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
@@ -434,6 +448,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
/* Combine the packet header write. VLAN is not consider here */
mb->hw_offload.l2_len = l2_len;
mb->hw_offload.l3_len = l3_len;
+ mb->hw_offload.l4_len = l4_len;
+ mb->hw_offload.mss = tx_mss;
mb->ol_flags = ol_flags;
}
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 68eccfa..b093911 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -135,6 +135,7 @@ struct rte_port {
struct fwd_stream *tx_stream; /**< Port TX stream, if unique */
unsigned int socket_id; /**< For NUMA support */
uint32_t tx_ol_flags;/**< Offload Flags of TX packets. */
+ uint16_t tx_mss; /**< MSS for segmentation offload. */
uint16_t tx_vlan_id; /**< Tag Id. in TX VLAN packets. */
void *fwd_ctx; /**< Forwarding mode context */
uint64_t rx_bad_ip_csum; /**< rx pkts with bad ip checksum */
@@ -486,6 +487,7 @@ void tx_vlan_reset(portid_t port_id);
void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value);
void tx_cksum_set(portid_t port_id, uint32_t ol_flags);
+void tso_set(portid_t port_id, uint16_t mss);
void set_verbose_level(uint16_t vb_level);
void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs);
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 1e63511..c65ab81 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -96,6 +96,17 @@ extern "C" {
#define PKT_TX_SCTP_CKSUM 0x00080000 /**< SCTP cksum of TX pkt. computed by NIC. */
#define PKT_TX_UDP_CKSUM 0x000C0000 /**< UDP cksum of TX pkt. computed by NIC. */
#define PKT_TX_IEEE1588_TMST 0x00100000 /**< TX IEEE1588 packet to timestamp. */
+/**
+ * TCP segmentation offload. To enable this offload feature for a
+ * packet to be transmitted on hardware supporting TSO:
+ * - set the PKT_TX_TCP_SEG flag in mbuf->ol_flags (this flag implies
+ * PKT_TX_IP_CKSUM and PKT_TX_TCP_CKSUM)
+ * - fill the mbuf->hw_offload information: l2_len, l3_len, l4_len, mss
+ * - calculate the pseudo header checksum and set it in the TCP header,
+ * as required when doing hardware TCP checksum offload
+ * - set the IP checksum to 0
+ */
+#define PKT_TX_TCP_SEG 0x00200000
/**
* Get the name of a RX offload flag
@@ -144,6 +155,7 @@ static inline const char *rte_get_tx_ol_flag_name(uint32_t mask)
case PKT_TX_SCTP_CKSUM: return "PKT_TX_SCTP_CKSUM";
case PKT_TX_UDP_CKSUM: return "PKT_TX_UDP_CKSUM";
case PKT_TX_IEEE1588_TMST: return "PKT_TX_IEEE1588_TMST";
+ case PKT_TX_TCP_SEG: return "PKT_TX_TCP_SEG";
default: return NULL;
}
}
@@ -157,11 +169,12 @@ union rte_hw_offload {
#define HW_OFFLOAD_L4_LEN_MASK 0xff
uint32_t l2_len:7; /**< L2 (MAC) Header Length. */
uint32_t l3_len:9; /**< L3 (IP) Header Length. */
- uint32_t reserved:16;
+ uint32_t l4_len:8; /**< L4 (TCP/UDP) Header Length. */
+ uint32_t reserved:8;
uint16_t vlan_tci;
/**< VLAN Tag Control Identifier (CPU order). */
- uint16_t reserved2;
+ uint16_t mss; /**< Maximum segment size. */
};
};
--
1.9.2
next prev parent reply other threads:[~2014-05-19 13:57 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-19 13:56 [dpdk-dev] [PATCH v2 00/17] ixgbe/mbuf: add TSO support Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 01/17] igb/ixgbe: fix IP checksum calculation Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 02/17] mbuf: rename RTE_MBUF_SCATTER_GATHER into RTE_MBUF_REFCNT Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 03/17] mbuf: remove rte_ctrlmbuf Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 04/17] mbuf: remove the rte_pktmbuf structure Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 05/17] mbuf: merge physaddr and buf_len in a bitfield Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 06/17] mbuf: cosmetic changes in rte_mbuf structure Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 07/17] mbuf: replace data pointer by an offset Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 08/17] mbuf: add functions to get the name of an ol_flag Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 09/17] mbuf: change ol_flags to 32 bits Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 10/17] mbuf: rename vlan_macip_len in hw_offload and increase its size Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 11/17] testpmd: modify source address to validate checksum calculation Olivier Matz
2014-05-19 13:56 ` Olivier Matz [this message]
2014-05-19 13:56 ` [dpdk-dev] [PATCH v2 13/17] ixgbe: support TCP segmentation offload Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [virtio-net-pmd PATCH v2 14/17] pmd: adapt to new rte_mbuf structure Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [vmxnet3-usermap PATCH v2 15/17] pmd: remove support of old dpdk versions Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [vmxnet3-usermap PATCH v2 16/17] pmd: adapt to new rte_mbuf structure Olivier Matz
2014-05-19 13:56 ` [dpdk-dev] [memnic PATCH v2 17/17] " Olivier Matz
2014-05-22 15:02 ` [dpdk-dev] [PATCH v2 00/17] add TSO support Thomas Monjalon
2014-05-22 16:09 ` Venkatesan, Venky
2014-05-23 14:22 ` Olivier MATZ
2014-05-23 14:43 ` Venkatesan, Venky
2014-05-26 11:59 ` Olivier MATZ
2014-05-23 12:47 ` Ananyev, Konstantin
2014-05-23 14:32 ` Olivier MATZ
2014-05-26 15:20 ` Ananyev, Konstantin
2014-11-03 7:32 ` [dpdk-dev] [PATCH v2 00/17] ixgbe/mbuf: " Liu, Jijiang
2014-11-03 10:12 ` Olivier MATZ
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1400507789-18453-13-git-send-email-olivier.matz@6wind.com \
--to=olivier.matz@6wind.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).