DPDK patches and discussions
 help / color / mirror / Atom feed
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Cc: Ivan Malov <ivan.malov@oktetlabs.ru>
Subject: [dpdk-dev] [PATCH 21/36] net/sfc: add header segments check for EF100 Tx datapath
Date: Tue, 13 Oct 2020 14:45:38 +0100	[thread overview]
Message-ID: <1602596753-32282-22-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1602596753-32282-1-git-send-email-arybchenko@solarflare.com>

From: Ivan Malov <ivan.malov@oktetlabs.ru>

EF100 native Tx datapath demands that packet header be contiguous
when partial checksum offloads are used since helper function is
used to calculate pseudo-header checksum (and the function requires
contiguous header).

Add an explicit check for this assumption and restructure the code
to avoid TSO header linearisation check since TSO header
linearisation is not done on EF100 native Tx datapath.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/sfc_dp_tx.h    | 85 +++++++++++++++++++++++++++-------
 drivers/net/sfc/sfc_ef100_tx.c |  4 +-
 drivers/net/sfc/sfc_ef10_tx.c  |  2 +-
 drivers/net/sfc/sfc_tx.c       |  2 +-
 4 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_tx.h b/drivers/net/sfc/sfc_dp_tx.h
index 67aa398b7f..bed8ce84aa 100644
--- a/drivers/net/sfc/sfc_dp_tx.h
+++ b/drivers/net/sfc/sfc_dp_tx.h
@@ -206,14 +206,38 @@ sfc_dp_tx_offload_capa(const struct sfc_dp_tx *dp_tx)
 	return dp_tx->dev_offload_capa | dp_tx->queue_offload_capa;
 }
 
+static inline unsigned int
+sfc_dp_tx_pkt_extra_hdr_segs(struct rte_mbuf **m_seg,
+			     unsigned int *header_len_remaining)
+{
+	unsigned int nb_extra_header_segs = 0;
+
+	while (rte_pktmbuf_data_len(*m_seg) < *header_len_remaining) {
+		*header_len_remaining -= rte_pktmbuf_data_len(*m_seg);
+		*m_seg = (*m_seg)->next;
+		++nb_extra_header_segs;
+	}
+
+	return nb_extra_header_segs;
+}
+
 static inline int
 sfc_dp_tx_prepare_pkt(struct rte_mbuf *m,
+			   unsigned int max_nb_header_segs,
+			   unsigned int tso_bounce_buffer_len,
 			   uint32_t tso_tcp_header_offset_limit,
 			   unsigned int max_fill_level,
 			   unsigned int nb_tso_descs,
 			   unsigned int nb_vlan_descs)
 {
 	unsigned int descs_required = m->nb_segs;
+	unsigned int tcph_off = ((m->ol_flags & PKT_TX_TUNNEL_MASK) ?
+				 m->outer_l2_len + m->outer_l3_len : 0) +
+				m->l2_len + m->l3_len;
+	unsigned int header_len = tcph_off + m->l4_len;
+	unsigned int header_len_remaining = header_len;
+	unsigned int nb_header_segs = 1;
+	struct rte_mbuf *m_seg = m;
 
 #ifdef RTE_LIBRTE_SFC_EFX_DEBUG
 	int ret;
@@ -229,10 +253,29 @@ sfc_dp_tx_prepare_pkt(struct rte_mbuf *m,
 	}
 #endif
 
-	if (m->ol_flags & PKT_TX_TCP_SEG) {
-		unsigned int tcph_off = m->l2_len + m->l3_len;
-		unsigned int header_len;
+	if (max_nb_header_segs != 0) {
+		/* There is a limit on the number of header segments. */
 
+		nb_header_segs +=
+		    sfc_dp_tx_pkt_extra_hdr_segs(&m_seg,
+						 &header_len_remaining);
+
+		if (unlikely(nb_header_segs > max_nb_header_segs)) {
+			/*
+			 * The number of header segments is too large.
+			 *
+			 * If TSO is requested and if the datapath supports
+			 * linearisation of TSO headers, allow the packet
+			 * to proceed with additional checks below.
+			 * Otherwise, throw an error.
+			 */
+			if ((m->ol_flags & PKT_TX_TCP_SEG) == 0 ||
+			    tso_bounce_buffer_len == 0)
+				return EINVAL;
+		}
+	}
+
+	if (m->ol_flags & PKT_TX_TCP_SEG) {
 		switch (m->ol_flags & PKT_TX_TUNNEL_MASK) {
 		case 0:
 			break;
@@ -242,30 +285,38 @@ sfc_dp_tx_prepare_pkt(struct rte_mbuf *m,
 			if (!(m->ol_flags &
 			      (PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IPV6)))
 				return EINVAL;
-
-			tcph_off += m->outer_l2_len + m->outer_l3_len;
 		}
 
-		header_len = tcph_off + m->l4_len;
-
 		if (unlikely(tcph_off > tso_tcp_header_offset_limit))
 			return EINVAL;
 
 		descs_required += nb_tso_descs;
 
 		/*
-		 * Extra descriptor that is required when a packet header
-		 * is separated from remaining content of the first segment.
+		 * If headers segments are already counted above, here
+		 * nothing is done since remaining length is smaller
+		 * then current segment size.
+		 */
+		nb_header_segs +=
+		    sfc_dp_tx_pkt_extra_hdr_segs(&m_seg,
+						 &header_len_remaining);
+
+		/*
+		 * Extra descriptor which is required when (a part of) payload
+		 * shares the same segment with (a part of) the header.
 		 */
-		if (rte_pktmbuf_data_len(m) > header_len) {
+		if (rte_pktmbuf_data_len(m_seg) > header_len_remaining)
 			descs_required++;
-		} else if (rte_pktmbuf_data_len(m) < header_len &&
-			 unlikely(header_len > SFC_TSOH_STD_LEN)) {
-			/*
-			 * Header linearization is required and
-			 * the header is too big to be linearized
-			 */
-			return EINVAL;
+
+		if (tso_bounce_buffer_len != 0) {
+			if (nb_header_segs > 1 &&
+			    unlikely(header_len > tso_bounce_buffer_len)) {
+				/*
+				 * Header linearization is required and
+				 * the header is too big to be linearized
+				 */
+				return EINVAL;
+			}
 		}
 	}
 
diff --git a/drivers/net/sfc/sfc_ef100_tx.c b/drivers/net/sfc/sfc_ef100_tx.c
index 41b1554f12..0dba5c8eee 100644
--- a/drivers/net/sfc/sfc_ef100_tx.c
+++ b/drivers/net/sfc/sfc_ef100_tx.c
@@ -95,9 +95,11 @@ sfc_ef100_tx_prepare_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 	for (i = 0; i < nb_pkts; i++) {
 		struct rte_mbuf *m = tx_pkts[i];
+		unsigned int max_nb_header_segs = 0;
 		int ret;
 
-		ret = sfc_dp_tx_prepare_pkt(m, 0, txq->max_fill_level, 0, 0);
+		ret = sfc_dp_tx_prepare_pkt(m, max_nb_header_segs, 0,
+					    0, txq->max_fill_level, 0, 0);
 		if (unlikely(ret != 0)) {
 			rte_errno = ret;
 			break;
diff --git a/drivers/net/sfc/sfc_ef10_tx.c b/drivers/net/sfc/sfc_ef10_tx.c
index 6fb4ac88a8..961689dc34 100644
--- a/drivers/net/sfc/sfc_ef10_tx.c
+++ b/drivers/net/sfc/sfc_ef10_tx.c
@@ -352,7 +352,7 @@ sfc_ef10_prepare_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			}
 		}
 #endif
-		ret = sfc_dp_tx_prepare_pkt(m,
+		ret = sfc_dp_tx_prepare_pkt(m, 0, SFC_TSOH_STD_LEN,
 				txq->tso_tcp_header_offset_limit,
 				txq->max_fill_level,
 				SFC_EF10_TSO_OPT_DESCS_NUM, 0);
diff --git a/drivers/net/sfc/sfc_tx.c b/drivers/net/sfc/sfc_tx.c
index 4ea614816a..d50d49ca56 100644
--- a/drivers/net/sfc/sfc_tx.c
+++ b/drivers/net/sfc/sfc_tx.c
@@ -718,7 +718,7 @@ sfc_efx_prepare_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 		 * insertion offload is requested regardless the offload
 		 * requested/supported.
 		 */
-		ret = sfc_dp_tx_prepare_pkt(tx_pkts[i],
+		ret = sfc_dp_tx_prepare_pkt(tx_pkts[i], 0, SFC_TSOH_STD_LEN,
 				encp->enc_tx_tso_tcp_header_offset_limit,
 				txq->max_fill_level, EFX_TX_FATSOV2_OPT_NDESCS,
 				1);
-- 
2.17.1


  parent reply	other threads:[~2020-10-13 13:52 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-13 13:45 [dpdk-dev] [PATCH 00/36] net/sfc: add EF100 support Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 01/36] doc: fix typo in EF10 Rx equal stride super-buffer name Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 02/36] doc: avoid references to removed config variables in net/sfc Andrew Rybchenko
2020-10-14 10:40   ` Ferruh Yigit
2020-10-13 13:45 ` [dpdk-dev] [PATCH 03/36] common/sfc_efx/base: factor out wrapper to set PHY link Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 04/36] common/sfc_efx/base: factor out MCDI wrapper to set LEDs Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 05/36] common/sfc_efx/base: fix PHY config failure on Riverhead Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 06/36] common/sfc_efx/base: add max number of Rx scatter buffers Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 07/36] net/sfc: check vs maximum " Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 08/36] net/sfc: log Rx/Tx doorbell addresses useful for debugging Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 09/36] net/sfc: add caps to specify if libefx supports Rx/Tx Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 10/36] net/sfc: add EF100 support Andrew Rybchenko
2020-10-14 10:40   ` Ferruh Yigit
2020-10-14 11:21     ` Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 11/36] net/sfc: use BAR layout discovery to find control window Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 12/36] net/sfc: implement libefx Rx packets event callbacks Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 13/36] net/sfc: implement libefx Tx descs complete " Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 14/36] net/sfc: log DMA allocations addresses Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 15/36] net/sfc: support datapath logs which may be compiled out Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 16/36] net/sfc: implement EF100 native Rx datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 17/36] net/sfc: implement EF100 native Tx datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 18/36] net/sfc: support multi-segment transmit for EF100 datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 19/36] net/sfc: support TCP and UDP checksum offloads for EF100 Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 20/36] net/sfc: support IPv4 header checksum offload for EF100 Tx Andrew Rybchenko
2020-10-13 13:45 ` Andrew Rybchenko [this message]
2020-10-13 13:45 ` [dpdk-dev] [PATCH 22/36] net/sfc: support tunnels for EF100 native Tx datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 23/36] net/sfc: support TSO for EF100 native datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 24/36] net/sfc: support tunnel TSO for EF100 native Tx datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 25/36] net/sfc: support Tx VLAN insertion offload for EF100 Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 26/36] net/sfc: support Rx checksum " Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 27/36] common/sfc_efx/base: simplify to request Rx prefix fields Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 28/36] common/sfc_efx/base: provide control to deliver RSS hash Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 29/36] common/sfc_efx/base: provide helper to check Rx prefix Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 30/36] net/sfc: map Rx offload RSS hash to corresponding RxQ flag Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 31/36] net/sfc: support per-queue Rx prefix for EF100 Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 32/36] net/sfc: support per-queue Rx RSS hash offload " Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 33/36] net/sfc: support user mark and flag Rx " Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 34/36] net/sfc: forward function control window offset to datapath Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 35/36] net/sfc: add Rx interrupts support for EF100 Andrew Rybchenko
2020-10-13 13:45 ` [dpdk-dev] [PATCH 36/36] doc: advertise Alveo SN1000 SmartNICs family support Andrew Rybchenko
2020-10-14 10:41   ` Ferruh Yigit
2020-10-14 11:15     ` Andrew Rybchenko
2020-10-14 10:41 ` [dpdk-dev] [PATCH 00/36] net/sfc: add EF100 support 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=1602596753-32282-22-git-send-email-arybchenko@solarflare.com \
    --to=arybchenko@solarflare.com \
    --cc=dev@dpdk.org \
    --cc=ivan.malov@oktetlabs.ru \
    /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).