[dpdk-dev] [PATCH 02/53] net/sfc/base: do not use Tx desc push with TSO descriptors

Andrew Rybchenko arybchenko at solarflare.com
Thu Nov 16 09:03:50 CET 2017


From: Mark Spender <mspender at solarflare.com>

Pushing TSO option descriptors is unsafe if pacer bypass is enabled,
so to make sure that doesn't happen never push TSO option descriptors.

Signed-off-by: Mark Spender <mspender at solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/base/ef10_tx.c | 56 ++++++++++++++++++++++++++++++++----------
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_tx.c b/drivers/net/sfc/base/ef10_tx.c
index 211d265..2666943 100644
--- a/drivers/net/sfc/base/ef10_tx.c
+++ b/drivers/net/sfc/base/ef10_tx.c
@@ -473,9 +473,9 @@ ef10_tx_qpost(
 }
 
 /*
- * This improves performance by pushing a TX descriptor at the same time as the
- * doorbell. The descriptor must be added to the TXQ, so that can be used if the
- * hardware decides not to use the pushed descriptor.
+ * This improves performance by, when possible, pushing a TX descriptor at the
+ * same time as the doorbell. The descriptor must be added to the TXQ, so that
+ * can be used if the hardware decides not to use the pushed descriptor.
  */
 			void
 ef10_tx_qpush(
@@ -495,16 +495,46 @@ ef10_tx_qpush(
 	offset = id * sizeof (efx_qword_t);
 
 	EFSYS_MEM_READQ(etp->et_esmp, offset, &desc);
-	EFX_POPULATE_OWORD_3(oword,
-	    ERF_DZ_TX_DESC_WPTR, wptr,
-	    ERF_DZ_TX_DESC_HWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_1),
-	    ERF_DZ_TX_DESC_LWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_0));
-
-	/* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
-	EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1, wptr, id);
-	EFSYS_PIO_WRITE_BARRIER();
-	EFX_BAR_TBL_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG, etp->et_index,
-				    &oword);
+
+	/*
+	 * Bug 65776: TSO option descriptors cannot be pushed if pacer bypass is
+	 * enabled on the event queue this transmit queue is attached to.
+	 *
+	 * To ensure the code is safe, it is easiest to simply test the type of
+	 * the descriptor to push, and only push it is if it not a TSO option
+	 * descriptor.
+	 */
+	if ((EFX_QWORD_FIELD(desc, ESF_DZ_TX_DESC_IS_OPT) != 1) ||
+	    (EFX_QWORD_FIELD(desc, ESF_DZ_TX_OPTION_TYPE) !=
+	    ESE_DZ_TX_OPTION_DESC_TSO)) {
+		/* Push the descriptor and update the wptr. */
+		EFX_POPULATE_OWORD_3(oword, ERF_DZ_TX_DESC_WPTR, wptr,
+		    ERF_DZ_TX_DESC_HWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_1),
+		    ERF_DZ_TX_DESC_LWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_0));
+
+		/* Ensure ordering of memory (descriptors) and PIO (doorbell) */
+		EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
+					    wptr, id);
+		EFSYS_PIO_WRITE_BARRIER();
+		EFX_BAR_TBL_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG,
+					    etp->et_index, &oword);
+	} else {
+		efx_dword_t dword;
+
+		/*
+		 * Only update the wptr. This is signalled to the hardware by
+		 * only writing one DWORD of the doorbell register.
+		 */
+		EFX_POPULATE_OWORD_1(oword, ERF_DZ_TX_DESC_WPTR, wptr);
+		dword = oword.eo_dword[2];
+
+		/* Ensure ordering of memory (descriptors) and PIO (doorbell) */
+		EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
+					    wptr, id);
+		EFSYS_PIO_WRITE_BARRIER();
+		EFX_BAR_TBL_WRITED2(enp, ER_DZ_TX_DESC_UPD_REG,
+				    etp->et_index, &dword, B_FALSE);
+	}
 }
 
 	__checkReturn	efx_rc_t
-- 
2.7.4



More information about the dev mailing list