From patchwork Tue Feb 2 15:23:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ivan Malov X-Patchwork-Id: 87639 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 08ADCA052A; Tue, 2 Feb 2021 16:24:02 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 88040240312; Tue, 2 Feb 2021 16:24:01 +0100 (CET) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 97DDD24030F; Tue, 2 Feb 2021 16:24:00 +0100 (CET) Received: from localhost.localdomain (unknown [5.144.123.104]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by shelob.oktetlabs.ru (Postfix) with ESMTPSA id 9F3D97F515; Tue, 2 Feb 2021 18:23:59 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 9F3D97F515 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=oktetlabs.ru; s=default; t=1612279439; bh=mzvlcqgrFpQWXJ+OhysRN8SzlnCj2ppmhF3W2xgBkcg=; h=From:To:Cc:Subject:Date; b=cuIqUohqfJed+NtAVWSgQD5SfR8uklACA/a7JuJmfv9mIahrrMcXScnxP/VKEkYcl rXE1EtjAzBb/k8ACE283o3UMoyIqtoazlVAPx2ZZom6llETetA5fmKuK9j2mkL4FKG zzGReZMq9QLd3/kCp7/zv1Qb1RpqGyC7dSfoq04A= From: Ivan Malov To: dev@dpdk.org Cc: stable@dpdk.org, Andrew Rybchenko , Andy Moreton , Igor Romanov , Robert Stonehouse , Mark Spender , Andrew Lee Date: Tue, 2 Feb 2021 18:23:45 +0300 Message-Id: <20210202152345.2878-1-ivan.malov@oktetlabs.ru> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH] net/sfc: add 8000-series EF10 hardware TSO bug workaround X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- 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);