DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround
@ 2021-02-02 15:23 Ivan Malov
  2021-02-03 10:37 ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
  0 siblings, 1 reply; 2+ messages in thread
From: Ivan Malov @ 2021-02-02 15:23 UTC (permalink / raw)
  To: dev
  Cc: stable, Andrew Rybchenko, Andy Moreton, Igor Romanov,
	Robert Stonehouse, Mark Spender, Andrew Lee

Innermost IP length and outer UDP datagram length must be
greater than or equal to the corresponding values derived
from the MSS; otherwise, the checksum offloads will break.

Fixes: c1ce2ba218f8 ("net/sfc: support tunnel TSO on EF10 native Tx datapath")
Fixes: 6bc985e41155 ("net/sfc: support TSO in EF10 Tx datapath")
Fixes: fec33d5bb3eb ("net/sfc: support firmware-assisted TSO")
Cc: stable@dpdk.org

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
 drivers/net/sfc/sfc_ef10_tx.c | 19 +++++++++++++++++++
 drivers/net/sfc/sfc_tso.c     |  7 +++++++
 drivers/net/sfc/sfc_tso.h     | 30 ++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 87fa40f3e..33d2d637c 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -481,6 +481,25 @@ sfc_ef10_xmit_tso_pkt(struct sfc_ef10_txq * const txq, struct rte_mbuf *m_seg,
 			needed_desc--;
 	}
 
+	/*
+	 * 8000-series EF10 hardware requires that innermost IP length
+	 * be greater than or equal to the value which each segment is
+	 * supposed to have; otherwise, TCP checksum will be incorrect.
+	 *
+	 * The same concern applies to outer UDP datagram length field.
+	 */
+	switch (m_seg->ol_flags & PKT_TX_TUNNEL_MASK) {
+	case PKT_TX_TUNNEL_VXLAN:
+		/* FALLTHROUGH */
+	case PKT_TX_TUNNEL_GENEVE:
+		sfc_tso_outer_udp_fix_len(first_m_seg, hdr_addr);
+		break;
+	default:
+		break;
+	}
+
+	sfc_tso_innermost_ip_fix_len(first_m_seg, hdr_addr, iph_off);
+
 	/*
 	 * Tx prepare has debug-only checks that offload flags are correctly
 	 * filled in in TSO mbuf. Use zero IPID if there is no IPv4 flag.
diff --git a/drivers/net/sfc/sfc_tso.c b/drivers/net/sfc/sfc_tso.c
index d6f111989..b090ef14d 100644
--- a/drivers/net/sfc/sfc_tso.c
+++ b/drivers/net/sfc/sfc_tso.c
@@ -140,6 +140,13 @@ sfc_efx_tso_do(struct sfc_efx_txq *txq, unsigned int idx,
 		tsoh = rte_pktmbuf_mtod(m, uint8_t *);
 	}
 
+	/*
+	 * 8000-series EF10 hardware requires that innermost IP length
+	 * be greater than or equal to the value which each segment is
+	 * supposed to have; otherwise, TCP checksum will be incorrect.
+	 */
+	sfc_tso_innermost_ip_fix_len(m, tsoh, nh_off);
+
 	/*
 	 * Handle IP header. Tx prepare has debug-only checks that offload flags
 	 * are correctly filled in in TSO mbuf. Use zero IPID if there is no
diff --git a/drivers/net/sfc/sfc_tso.h b/drivers/net/sfc/sfc_tso.h
index 8597c2868..361aa2219 100644
--- a/drivers/net/sfc/sfc_tso.h
+++ b/drivers/net/sfc/sfc_tso.h
@@ -38,6 +38,36 @@ sfc_tso_ip4_get_ipid(const uint8_t *pkt_hdrp, size_t ip_hdr_off)
 	return rte_be_to_cpu_16(ipid);
 }
 
+static inline void
+sfc_tso_outer_udp_fix_len(const struct rte_mbuf *m, uint8_t *tsoh)
+{
+	rte_be16_t len = rte_cpu_to_be_16(m->l2_len + m->l3_len + m->l4_len +
+					  m->tso_segsz);
+
+	rte_memcpy(tsoh + m->outer_l2_len + m->outer_l3_len +
+		   offsetof(struct rte_udp_hdr, dgram_len),
+		   &len, sizeof(len));
+}
+
+static inline void
+sfc_tso_innermost_ip_fix_len(const struct rte_mbuf *m, uint8_t *tsoh,
+			     size_t iph_ofst)
+{
+	size_t ip_payload_len = m->l4_len + m->tso_segsz;
+	size_t field_ofst;
+	rte_be16_t len;
+
+	if (m->ol_flags & PKT_TX_IPV4) {
+		field_ofst = offsetof(struct rte_ipv4_hdr, total_length);
+		len = rte_cpu_to_be_16(m->l3_len + ip_payload_len);
+	} else {
+		field_ofst = offsetof(struct rte_ipv6_hdr, payload_len);
+		len = rte_cpu_to_be_16(ip_payload_len);
+	}
+
+	rte_memcpy(tsoh + iph_ofst + field_ofst, &len, sizeof(len));
+}
+
 unsigned int sfc_tso_prepare_header(uint8_t *tsoh, size_t header_len,
 				    struct rte_mbuf **in_seg, size_t *in_off);
 
-- 
2.20.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [dpdk-dev] [dpdk-stable] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround
  2021-02-02 15:23 [dpdk-dev] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround Ivan Malov
@ 2021-02-03 10:37 ` Ferruh Yigit
  0 siblings, 0 replies; 2+ messages in thread
From: Ferruh Yigit @ 2021-02-03 10:37 UTC (permalink / raw)
  To: Ivan Malov, dev
  Cc: stable, Andrew Rybchenko, Andy Moreton, Igor Romanov,
	Robert Stonehouse, Mark Spender, Andrew Lee

On 2/2/2021 3:23 PM, Ivan Malov wrote:
> Innermost IP length and outer UDP datagram length must be
> greater than or equal to the corresponding values derived
> from the MSS; otherwise, the checksum offloads will break.
> 
> Fixes: c1ce2ba218f8 ("net/sfc: support tunnel TSO on EF10 native Tx datapath")
> Fixes: 6bc985e41155 ("net/sfc: support TSO in EF10 Tx datapath")
> Fixes: fec33d5bb3eb ("net/sfc: support firmware-assisted TSO")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
> Reviewed-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>

Applied to dpdk-next-net/main, thanks.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-02-03 10:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-02 15:23 [dpdk-dev] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround Ivan Malov
2021-02-03 10:37 ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit

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).