All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivan Malov <ivan.malov@oktetlabs.ru>
To: dev@dpdk.org
Cc: stable@dpdk.org, Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,
	Andy Moreton <amoreton@xilinx.com>,
	Igor Romanov <igor.romanov@oktetlabs.ru>,
	Robert Stonehouse <rstonehouse@solarflare.com>,
	Mark Spender <mspender@solarflare.com>,
	Andrew Lee <alee@solarflare.com>
Subject: [dpdk-dev] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround
Date: Tue,  2 Feb 2021 18:23:45 +0300	[thread overview]
Message-ID: <20210202152345.2878-1-ivan.malov@oktetlabs.ru> (raw)

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


             reply	other threads:[~2021-02-02 15:24 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-02 15:23 Ivan Malov [this message]
2021-02-03 10:37 ` [dpdk-dev] [dpdk-stable] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround Ferruh Yigit

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=20210202152345.2878-1-ivan.malov@oktetlabs.ru \
    --to=ivan.malov@oktetlabs.ru \
    --cc=alee@solarflare.com \
    --cc=amoreton@xilinx.com \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=dev@dpdk.org \
    --cc=igor.romanov@oktetlabs.ru \
    --cc=mspender@solarflare.com \
    --cc=rstonehouse@solarflare.com \
    --cc=stable@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.