From: Maxime Peim <maxime.peim@gmail.com>
To: dev@dpdk.org
Cc: dsosnowski@nvidia.com, viacheslavo@nvidia.com, bingz@nvidia.com,
orika@nvidia.com, suanmingm@nvidia.com, matan@nvidia.com
Subject: [PATCH] net/mlx5: prepend implicit items in sync flow creation path
Date: Thu, 9 Apr 2026 20:56:34 +0200 [thread overview]
Message-ID: <20260409185634.3996187-1-maxime.peim@gmail.com> (raw)
In eSwitch mode, the async (template) flow creation path automatically
prepends implicit match items to scope flow rules to the correct
representor port:
- Ingress: REPRESENTED_PORT item matching dev->data->port_id
- Egress: REG_C_0 TAG item matching the port's tx tag value
The sync path (flow_hw_list_create) was missing this logic, causing all
flow rules created via the non-template API to match traffic from all
ports rather than being scoped to the specific representor.
Add the same implicit item prepending to flow_hw_list_create, right
after pattern validation and before any branching (sample/RSS/single/
prefix), mirroring the behavior of flow_hw_pattern_template_create
and flow_hw_get_rule_items. The ingress case prepends
REPRESENTED_PORT with the current port_id; the egress case prepends
MLX5_RTE_FLOW_ITEM_TYPE_TAG with REG_C_0 value/mask (skipped when
user provides an explicit SQ item).
Also fix a pre-existing bug where 'return split' on metadata split
failure returned a negative int cast to uintptr_t, which callers
would treat as a valid flow handle instead of an error.
Signed-off-by: Maxime Peim <maxime.peim@gmail.com>
---
drivers/net/mlx5/mlx5_flow_hw.c | 78 ++++++++++++++++++++++++++++++---
1 file changed, 73 insertions(+), 5 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index bca5b2769e..d05cd2075c 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -14275,6 +14275,7 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
uint64_t item_flags = 0;
uint64_t action_flags = mlx5_flow_hw_action_flags_get(actions, &qrss, &mark,
&encap_idx, &actions_n, error);
+ struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_flow_hw_split_resource resource = {
.suffix = {
.attr = attr,
@@ -14282,6 +14283,28 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
.actions = actions,
},
};
+ struct rte_flow_item *prepend_items = NULL;
+ struct rte_flow_item_ethdev port_spec = {.port_id = dev->data->port_id};
+ struct rte_flow_item port = {
+ .type = RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT,
+ .spec = &port_spec,
+ .mask = &rte_flow_item_ethdev_mask,
+ };
+ struct mlx5_rte_flow_item_tag tag_v = {
+ .id = REG_C_0,
+ .data = flow_hw_tx_tag_regc_value(dev),
+ };
+ struct mlx5_rte_flow_item_tag tag_m = {
+ .id = REG_C_0,
+ .data = flow_hw_tx_tag_regc_mask(dev),
+ };
+ struct rte_flow_item tag = {
+ .type = (enum rte_flow_item_type)MLX5_RTE_FLOW_ITEM_TYPE_TAG,
+ .spec = &tag_v,
+ .mask = &tag_m,
+ .last = NULL,
+ };
+ uint32_t nb_items;
struct rte_flow_error shadow_error = {0, };
const struct rte_flow_pattern_template_attr pattern_template_attr = {
.relaxed_matching = 0,
@@ -14296,13 +14319,50 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
if (ret < 0)
return 0;
+ nb_items = ret;
+
+ /*
+ * In eSwitch mode, the async (template) path automatically prepends
+ * implicit items to scope flow rules to the correct representor port:
+ * - Ingress: REPRESENTED_PORT item matching dev->data->port_id
+ * - Egress: REG_C_0 TAG item matching the port's tx tag value
+ * Mirror this behavior in the sync path so rules are not shared
+ * across all eSwitch ports.
+ */
+ if (priv->sh->config.dv_esw_en &&
+ attr->ingress && !attr->egress && !attr->transfer) {
+ prepend_items = flow_hw_prepend_item(items, nb_items,
+ &port, error);
+ if (!prepend_items)
+ return 0;
+ items = prepend_items;
+ resource.suffix.items = items;
+ } else if (priv->sh->config.dv_esw_en &&
+ !attr->ingress && attr->egress && !attr->transfer) {
+ if (item_flags & MLX5_FLOW_ITEM_SQ) {
+ DRV_LOG(DEBUG,
+ "Port %u omitting implicit REG_C_0 match for egress "
+ "pattern template",
+ dev->data->port_id);
+ goto setup_pattern;
+ }
+ prepend_items = flow_hw_prepend_item(items, nb_items,
+ &tag, error);
+ if (!prepend_items)
+ return 0;
+ items = prepend_items;
+ resource.suffix.items = items;
+ }
+setup_pattern:
RTE_SET_USED(encap_idx);
if (!error)
error = &shadow_error;
split = mlx5_flow_nta_split_metadata(dev, attr, actions, qrss, action_flags,
actions_n, external, &resource, error);
- if (split < 0)
- return split;
+ if (split < 0) {
+ mlx5_free(prepend_items);
+ return 0;
+ }
/* Update the metadata copy table - MLX5_FLOW_MREG_CP_TABLE_GROUP */
if (((attr->ingress && attr->group != MLX5_FLOW_MREG_CP_TABLE_GROUP) ||
@@ -14315,8 +14375,10 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
flow = mlx5_nta_sample_flow_list_create(dev, type, attr, items, actions,
item_flags, action_flags, error);
- if (flow != NULL)
+ if (flow != NULL) {
+ mlx5_free(prepend_items);
return (uintptr_t)flow;
+ }
goto free;
}
if (action_flags & MLX5_FLOW_ACTION_RSS) {
@@ -14328,8 +14390,10 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
if (flow) {
flow->nt2hws->rix_mreg_copy = cpy_idx;
cpy_idx = 0;
- if (!split)
+ if (!split) {
+ mlx5_free(prepend_items);
return (uintptr_t)flow;
+ }
goto prefix_flow;
}
goto free;
@@ -14343,8 +14407,10 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
if (flow) {
flow->nt2hws->rix_mreg_copy = cpy_idx;
cpy_idx = 0;
- if (!split)
+ if (!split) {
+ mlx5_free(prepend_items);
return (uintptr_t)flow;
+ }
/* Fall Through to prefix flow creation. */
}
prefix_flow:
@@ -14357,6 +14423,7 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
flow->nt2hws->chaned_flow = 1;
SLIST_INSERT_AFTER(prfx_flow, flow, nt2hws->next);
mlx5_flow_nta_split_resource_free(dev, &resource);
+ mlx5_free(prepend_items);
return (uintptr_t)prfx_flow;
}
free:
@@ -14368,6 +14435,7 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
mlx5_flow_nta_del_copy_action(dev, cpy_idx);
if (split > 0)
mlx5_flow_nta_split_resource_free(dev, &resource);
+ mlx5_free(prepend_items);
return 0;
}
--
2.43.0
reply other threads:[~2026-04-11 13:58 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20260409185634.3996187-1-maxime.peim@gmail.com \
--to=maxime.peim@gmail.com \
--cc=bingz@nvidia.com \
--cc=dev@dpdk.org \
--cc=dsosnowski@nvidia.com \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=suanmingm@nvidia.com \
--cc=viacheslavo@nvidia.com \
/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