patch 'net/mlx5: fix eCPRI match on HWS root table' has been queued to stable release 25.11.3

Kevin Traynor ktraynor at redhat.com
Thu Jul 23 19:15:48 CEST 2026


Hi,

FYI, your patch has been queued to stable release 25.11.3

Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 07/27/26. So please
shout if anyone has objections.

Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.

Queued patches are on a temporary branch at:
https://github.com/kevintraynor/dpdk-stable

This queued commit can be viewed at:
https://github.com/kevintraynor/dpdk-stable/commit/cd44ccaf81e32d2431a127491d8a098d903bf4a1

Thanks.

Kevin

---
>From cd44ccaf81e32d2431a127491d8a098d903bf4a1 Mon Sep 17 00:00:00 2001
From: Bing Zhao <bingz at nvidia.com>
Date: Thu, 4 Jun 2026 06:52:22 +0300
Subject: [PATCH] net/mlx5: fix eCPRI match on HWS root table

[ upstream commit feb377aea6c6baea4b04e4aeb4238f5603415c46 ]

When inserting a rule on the root table in HWS mode, the DV
interfaces are still being used for the matcher and value
translation.

For item eCPRI in HWS mode, the DWs of message header and body may be
0 for a valid rule. So we need to use some flags on root table to
decide if the sample ID and matching value should be set for the
rule. Since the table and rule may be created in turn for
asynchronous flow API, the flags should be per table to avoid
over-written. In SWS mode, nothing would be done separately for the
matcher itself.

On the non-root table in HWS, the callbacks to fill the WQE will
handle such case automatically.

Fixes: 93c7d4c22628 ("net/mlx5: support eCPRI with HWS")

Signed-off-by: Bing Zhao <bingz at nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr_matcher.c |  1 +
 drivers/net/mlx5/hws/mlx5dr_matcher.h |  1 +
 drivers/net/mlx5/hws/mlx5dr_rule.c    |  1 +
 drivers/net/mlx5/mlx5_flow.h          |  7 +++
 drivers/net/mlx5/mlx5_flow_dv.c       | 77 +++++++++++++++++++++------
 5 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index 7d77cf4a3e..310c79d907 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -1382,4 +1382,5 @@ static int mlx5dr_matcher_init_root(struct mlx5dr_matcher *matcher)
 	pthread_spin_unlock(&ctx->ctrl_lock);
 
+	matcher->hws_root_match_flags = flow_attr.hws_root_match_flags;
 	return 0;
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h
index ef42b7de6b..fbcf9fe09e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.h
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h
@@ -83,4 +83,5 @@ struct mlx5dr_matcher {
 	/* enum mlx5dr_matcher_flags */
 	uint8_t flags;
+	uint32_t hws_root_match_flags;
 	struct mlx5dr_devx_obj *end_ft;
 	struct mlx5dr_matcher *col_matcher;
diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.c b/drivers/net/mlx5/hws/mlx5dr_rule.c
index 4f53734eec..f1e9b7550e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_rule.c
+++ b/drivers/net/mlx5/hws/mlx5dr_rule.c
@@ -742,4 +742,5 @@ int mlx5dr_rule_create_root_no_comp(struct mlx5dr_rule *rule,
 
 	flow_attr.tbl_type = rule->matcher->tbl->type;
+	flow_attr.hws_root_match_flags = rule->matcher->hws_root_match_flags;
 
 	ret = flow_dv_translate_items_hws(items, &flow_attr, value->match_buf,
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 030f51c509..5d63ec59bd 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -118,4 +118,7 @@ enum mlx5_indirect_type {
 	 ((MLX5_INDIRECT_ACTION_TYPE_CT << MLX5_INDIRECT_ACTION_TYPE_OFFSET) | (index)))
 
+#define MLX5_EMPTY_ECPRI_TYPE_MASK RTE_BIT32(0)
+#define MLX5_EMPTY_ECPRI_BODY_MASK RTE_BIT32(1)
+
 enum mlx5_indirect_list_type {
 	MLX5_INDIRECT_ACTION_LIST_TYPE_ERR = 0,
@@ -1265,4 +1268,5 @@ struct mlx5_flow_attr {
 	uint32_t act_flags;
 	uint32_t tbl_type; /* Flow table type. */
+	uint32_t hws_root_match_flags;
 };
 
@@ -1985,4 +1989,6 @@ struct mlx5_flow_workspace {
 	/* Indicates if need to skip matcher register in translate. */
 	uint32_t mark:1; /* Indicates if flow contains mark action. */
+	uint32_t empty_ecpri_type_mask:1; /* Indicates if eCPRI type was not masked. */
+	uint32_t empty_ecpri_body_mask:1; /* Indicates if 1st DW of eCPRI payload was not masked. */
 	uint32_t vport_meta_tag; /* Used for vport index match. */
 };
@@ -2018,4 +2024,5 @@ struct mlx5_dv_matcher_workspace {
 	const struct rte_flow_item *gre_item; /* Flow GRE item. */
 	const struct rte_flow_item *integrity_items[2];
+	uint32_t *p_root_flags;
 };
 
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 69d3bcfa3d..7ca97476e0 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -7789,5 +7789,5 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 				RTE_BE32(((const struct rte_ecpri_common_hdr) {
 					.type = 0xFF,
-					}).u32),
+				}).u32),
 			},
 			.dummy[0] = 0xffffffff,
@@ -11389,4 +11389,18 @@ flow_dv_translate_item_gtp_psc(void *key, const struct rte_flow_item *item,
 }
 
+
+static inline void
+flow_dv_set_ecpri_sample1(void *misc4_v,
+			  const struct rte_flow_item_ecpri *ecpri_m,
+			  const struct rte_flow_item_ecpri *ecpri_v,
+			  uint32_t sample1)
+{
+	void *dw_v;
+	dw_v = MLX5_ADDR_OF(fte_match_set_misc4, misc4_v, prog_sample_field_value_1);
+	*(uint32_t *)dw_v = ecpri_v->hdr.dummy[0] & ecpri_m->hdr.dummy[0];
+	/* Sample#1, to match message body, offset 4. */
+	MLX5_SET(fte_match_set_misc4, misc4_v, prog_sample_field_id_1, sample1);
+}
+
 /**
  * Add eCPRI item to matcher and to the value.
@@ -11406,4 +11420,5 @@ static void
 flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
 			     const struct rte_flow_item *item,
+			     struct mlx5_dv_matcher_workspace *wks,
 			     uint64_t last_item, uint32_t key_type)
 {
@@ -11434,8 +11449,8 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
 		}
 	}
+	/* HWS matcher does need a non-empty mask. */
 	if (MLX5_ITEM_VALID(item, key_type))
 		return;
-	MLX5_ITEM_UPDATE(item, key_type, ecpri_v, ecpri_m,
-		&rte_flow_item_ecpri_mask);
+	MLX5_ITEM_UPDATE(item, key_type, ecpri_v, ecpri_m, &rte_flow_item_ecpri_mask);
 	/*
 	 * Maximal four DW samples are supported in a single matching now.
@@ -11444,6 +11459,20 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
 	 * 2. ID of a message: one or two bytes, mask 0xffff0000 or 0xff000000
 	 *    if any.
+	 * Translation also handles the following cases.
+	 * 1. HWS mode may face a case with NULL mask and value all zeros.
+	 * 2. Matching all eCPRI packets will be done in ETH / VLAN item.
+	 * 3. If type is not masked, then message body will not be masked either, forcefully.
 	 */
-	if (!ecpri_m->hdr.common.u32)
+	if (key_type == MLX5_SET_MATCHER_HS_M) {
+		if (!ecpri_m->hdr.common.u32) {
+			*wks->p_root_flags |= MLX5_EMPTY_ECPRI_TYPE_MASK;
+			return;
+		}
+		/* Initialized with 0, this should not hit. */
+		*wks->p_root_flags &= ~MLX5_EMPTY_ECPRI_TYPE_MASK;
+	}
+	if (key_type == MLX5_SET_MATCHER_HS_V && (*wks->p_root_flags & MLX5_EMPTY_ECPRI_TYPE_MASK))
+		return;
+	if ((key_type & MLX5_SET_MATCHER_SW) && !ecpri_m->hdr.common.u32)
 		return;
 	samples = priv->sh->ecpri_parser.ids;
@@ -11461,20 +11490,26 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
 	 * Some wildcard rules only matching type field should be supported.
 	 */
-	if (ecpri_m->hdr.dummy[0]) {
-		if (key_type == MLX5_SET_MATCHER_SW_M)
-			common.u32 = rte_be_to_cpu_32(ecpri_vv->hdr.common.u32);
-		else
-			common.u32 = rte_be_to_cpu_32(ecpri_v->hdr.common.u32);
+	if (key_type == MLX5_SET_MATCHER_HS_M) {
+		if (!ecpri_m->hdr.dummy[0]) {
+			*wks->p_root_flags |= MLX5_EMPTY_ECPRI_BODY_MASK;
+			return;
+		}
+		*wks->p_root_flags &= ~MLX5_EMPTY_ECPRI_BODY_MASK;
+	}
+	if (key_type == MLX5_SET_MATCHER_HS_V && (*wks->p_root_flags & MLX5_EMPTY_ECPRI_BODY_MASK))
+		return;
+	if (key_type & MLX5_SET_MATCHER_SW) {
+		if (!ecpri_m->hdr.dummy[0])
+			return;
+		common.u32 = rte_be_to_cpu_32(ecpri_vv->hdr.common.u32);
+	} else if (key_type == MLX5_SET_MATCHER_HS_V) {
+		common.u32 = rte_be_to_cpu_32(ecpri_v->hdr.common.u32);
+	}
+	if (key_type != MLX5_SET_MATCHER_HS_M) {
 		switch (common.type) {
 		case RTE_ECPRI_MSG_TYPE_IQ_DATA:
 		case RTE_ECPRI_MSG_TYPE_RTC_CTRL:
 		case RTE_ECPRI_MSG_TYPE_DLY_MSR:
-			dw_v = MLX5_ADDR_OF(fte_match_set_misc4, misc4_v,
-					    prog_sample_field_value_1);
-			*(uint32_t *)dw_v = ecpri_v->hdr.dummy[0] &
-					    ecpri_m->hdr.dummy[0];
-			/* Sample#1, to match message body, offset 4. */
-			MLX5_SET(fte_match_set_misc4, misc4_v,
-				 prog_sample_field_id_1, samples[1]);
+			flow_dv_set_ecpri_sample1(misc4_v, ecpri_v, ecpri_m, samples[1]);
 			break;
 		default:
@@ -11482,4 +11517,11 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
 			break;
 		}
+	} else {
+		/* When MLX5_SET_MATCHER_HS_M on root table (default value),
+		 * the sample ID and mask should be set, or else prog_sample_field_id_1 will
+		 * be zero and a mismatch with the HWS rule.
+		 * Empty body mask for a matcher returns directly in the previous lines.
+		 */
+		flow_dv_set_ecpri_sample1(misc4_v, ecpri_v, ecpri_m, samples[1]);
 	}
 }
@@ -14481,5 +14523,5 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
 		}
 		flow_dv_translate_item_ecpri
-				(dev, key, items, last_item, key_type);
+				(dev, key, items, wks, last_item, key_type);
 		/* No other protocol should follow eCPRI layer. */
 		last_item = MLX5_FLOW_LAYER_ECPRI;
@@ -14678,4 +14720,5 @@ __flow_dv_translate_items_hws(const struct rte_flow_item *items,
 		.rss_desc = &rss_desc,
 		.group = attr->group,
+		.p_root_flags = &attr->hws_root_match_flags,
 	};
 	int ret = 0;
-- 
2.55.0

---
  Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- -	2026-07-23 17:58:01.097202865 +0100
+++ 0085-net-mlx5-fix-eCPRI-match-on-HWS-root-table.patch	2026-07-23 17:57:58.711918506 +0100
@@ -1 +1 @@
-From feb377aea6c6baea4b04e4aeb4238f5603415c46 Mon Sep 17 00:00:00 2001
+From cd44ccaf81e32d2431a127491d8a098d903bf4a1 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit feb377aea6c6baea4b04e4aeb4238f5603415c46 ]
+
@@ -22 +23,0 @@
-Cc: stable at dpdk.org
@@ -35 +36 @@
-index 8c07ea8882..511f394448 100644
+index 7d77cf4a3e..310c79d907 100644
@@ -55 +56 @@
-index 0fda0a2d71..fe69721c92 100644
+index 4f53734eec..f1e9b7550e 100644
@@ -63 +64 @@
- 	ret = mlx5_flow_dv_translate_items_hws(items, &flow_attr, value->match_buf,
+ 	ret = flow_dv_translate_items_hws(items, &flow_attr, value->match_buf,
@@ -65 +66 @@
-index 3f5ba55bf9..3415b4722e 100644
+index 030f51c509..5d63ec59bd 100644
@@ -82 +83 @@
-@@ -1986,4 +1990,6 @@ struct mlx5_flow_workspace {
+@@ -1985,4 +1989,6 @@ struct mlx5_flow_workspace {
@@ -89 +90 @@
-@@ -2019,4 +2025,5 @@ struct mlx5_dv_matcher_workspace {
+@@ -2018,4 +2024,5 @@ struct mlx5_dv_matcher_workspace {
@@ -96 +97 @@
-index c2a2874913..307354c886 100644
+index 69d3bcfa3d..7ca97476e0 100644
@@ -99 +100 @@
-@@ -7799,5 +7799,5 @@ mlx5_flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
+@@ -7789,5 +7789,5 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
@@ -106 +107 @@
-@@ -11402,4 +11402,18 @@ flow_dv_translate_item_gtp_psc(void *key, const struct rte_flow_item *item,
+@@ -11389,4 +11389,18 @@ flow_dv_translate_item_gtp_psc(void *key, const struct rte_flow_item *item,
@@ -125 +126 @@
-@@ -11419,4 +11433,5 @@ static void
+@@ -11406,4 +11420,5 @@ static void
@@ -131 +132 @@
-@@ -11447,8 +11462,8 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
+@@ -11434,8 +11449,8 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
@@ -142 +143 @@
-@@ -11457,6 +11472,20 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
+@@ -11444,6 +11459,20 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
@@ -164 +165 @@
-@@ -11474,20 +11503,26 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
+@@ -11461,20 +11490,26 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
@@ -203 +204 @@
-@@ -11495,4 +11530,11 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
+@@ -11482,4 +11517,11 @@ flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *key,
@@ -215 +216 @@
-@@ -14502,5 +14544,5 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
+@@ -14481,5 +14523,5 @@ flow_dv_translate_items(struct rte_eth_dev *dev,
@@ -222 +223 @@
-@@ -14699,4 +14741,5 @@ mlx5_flow_dv_translate_items_hws_impl(const struct rte_flow_item *items,
+@@ -14678,4 +14720,5 @@ __flow_dv_translate_items_hws(const struct rte_flow_item *items,



More information about the stable mailing list