[dpdk-dev] [PATCH] net/i40e: add flow mark support to sse path

Harry van Haaren harry.van.haaren at intel.com
Fri May 31 20:04:40 CEST 2019


This commit enables the "FD ID" or flow-director mark
capability with the SSE vector PMD for 32 byte descriptors.

Suggested-by: Mesut Ergin <mesut.a.ergin at intel.com>
Signed-off-by: Harry van Haaren <harry.van.haaren at intel.com>

---

Hey Folks,

This v1 is expected to have some performance impact due to adding stores
to the data path. These can be reduced by blending the data into the register
which is later stored - however this would require larger code changes, and
be more difficult to review. As a v1 patch, this achieves the same goal.

Please review the concept, and I'll rework the implementation to be more
performant for the v2 by adding the required blending for ol_flags.

Cheers, -Harry

---

 drivers/net/i40e/i40e_rxtx.c         |  6 -----
 drivers/net/i40e/i40e_rxtx.h         |  7 ++++++
 drivers/net/i40e/i40e_rxtx_vec_sse.c | 37 ++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 7618153e2..6190ddd07 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -172,12 +172,6 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-#define I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK   0x03
-#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID  0x01
-#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FLEX   0x02
-#define I40E_RX_DESC_EXT_STATUS_FLEXBL_MASK   0x03
-#define I40E_RX_DESC_EXT_STATUS_FLEXBL_FLEX   0x01
-
 static inline uint64_t
 i40e_rxd_build_fdir(volatile union i40e_rx_desc *rxdp, struct rte_mbuf *mb)
 {
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 3fc619af9..23de35e42 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -32,6 +32,13 @@
 
 #define I40E_TX_MIN_PKT_LEN 17
 
+/* Shared FDIR masks between scalar / vector drivers */
+#define I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK   0x03
+#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID  0x01
+#define I40E_RX_DESC_EXT_STATUS_FLEXBH_FLEX   0x02
+#define I40E_RX_DESC_EXT_STATUS_FLEXBL_MASK   0x03
+#define I40E_RX_DESC_EXT_STATUS_FLEXBL_FLEX   0x01
+
 #undef container_of
 #define container_of(ptr, type, member) ({ \
 		typeof(((type *)0)->member)(*__mptr) = (ptr); \
diff --git a/drivers/net/i40e/i40e_rxtx_vec_sse.c b/drivers/net/i40e/i40e_rxtx_vec_sse.c
index 3b22588c5..180d00b79 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_sse.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_sse.c
@@ -206,6 +206,31 @@ desc_to_ptype_v(__m128i descs[4], struct rte_mbuf **rx_pkts,
 	rx_pkts[3]->packet_type = ptype_tbl[_mm_extract_epi8(ptype1, 8)];
 }
 
+/* Reads the FDIR ID flags from the 32B descriptors' extended status,
+ * and if FDIR_ID mark is set, pushes the data to the mbuf->hash.fdir.hi.
+ */
+static inline void
+desc_to_fdir_mark(__m128i v_desc_qw23, struct rte_mbuf *rx_pkt)
+{
+	/* Extract the extended status */
+	uint32_t ext_sts = _mm_extract_epi16(v_desc_qw23, 0);
+	uint32_t fdir_data = rte_le_to_cpu_32(
+			_mm_extract_epi32(v_desc_qw23, 3));
+
+	/* Check for FD ID mark valid */
+	uint32_t flexbh = (rte_le_to_cpu_32(ext_sts) >>
+		I40E_RX_DESC_EXT_STATUS_FLEXBH_SHIFT) &
+		I40E_RX_DESC_EXT_STATUS_FLEXBH_MASK;
+
+	/* Branch-free generation of mask for data */
+	uint32_t fd_id_valid = (flexbh == I40E_RX_DESC_EXT_STATUS_FLEXBH_FD_ID);
+	uint64_t use_data_mask = (!fd_id_valid) - 1;
+
+	/* Always store, mask will zero out if not valid */
+	rx_pkt->hash.fdir.hi = (use_data_mask & fdir_data);
+	rx_pkt->ol_flags |= (PKT_RX_FDIR_ID & use_data_mask);
+}
+
  /*
  * Notice:
  * - nb_pkts < RTE_I40E_DESCS_PER_LOOP, just return no packet
@@ -441,6 +466,18 @@ _recv_raw_pkts_vec(struct i40e_rx_queue *rxq, struct rte_mbuf **rx_pkts,
 		_mm_storeu_si128((void *)&rx_pkts[pos]->rx_descriptor_fields1,
 				 pkt_mb1);
 		desc_to_ptype_v(descs, &rx_pkts[pos], ptype_tbl);
+
+		/* Extract FDIR ID from 2nd half of descriptor, update mbuf */
+		__m128i descs_qw23;
+		descs_qw23 = _mm_loadu_si128((__m128i*)&(rxdp + 0)->wb.qword2);
+		desc_to_fdir_mark(descs_qw23, rx_pkts[pos + 0]);
+		descs_qw23 = _mm_loadu_si128((__m128i*)&(rxdp + 1)->wb.qword2);
+		desc_to_fdir_mark(descs_qw23, rx_pkts[pos + 1]);
+		descs_qw23 = _mm_loadu_si128((__m128i*)&(rxdp + 2)->wb.qword2);
+		desc_to_fdir_mark(descs_qw23, rx_pkts[pos + 2]);
+		descs_qw23 = _mm_loadu_si128((__m128i*)&(rxdp + 3)->wb.qword2);
+		desc_to_fdir_mark(descs_qw23, rx_pkts[pos + 3]);
+
 		/* C.4 calc avaialbe number of desc */
 		var = __builtin_popcountll(_mm_cvtsi128_si64(staterr));
 		nb_pkts_recd += var;
-- 
2.17.1



More information about the dev mailing list