|SUCCESS| [v3] net/mlx5: prepend implicit items in sync flow creation path

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Thu Apr 30 01:30:52 CEST 2026


Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/163341

_AI Code Review_

=== Patch Review: series.patch (via Claude) ===
Review date: 2026-04-29

Commit: [git sha needed - not provided in patch]
Author: Maxime Peim <maxime.peim at gmail.com>
Subject: [PATCH v3] net/mlx5: prepend implicit items in sync flow creation path

This patch adds implicit item prepending logic to the sync flow creation
path to match the async template path behavior in eSwitch mode, and fixes
a bug where negative error codes were cast to valid pointers.

> diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
> index bca5b2769e..ffd7a0076f 100644
> --- a/drivers/net/mlx5/mlx5_flow_hw.c
> +++ b/drivers/net/mlx5/mlx5_flow_hw.c
> @@ -9255,33 +9255,40 @@ pattern_template_validate(struct rte_eth_dev *dev,
>  	return -ret;
>  }
>  
> -/**
> - * Create flow item template.
> +/*
> + * Validate the user-supplied items and, in eSwitch mode, prepend the implicit
> + * scoping item so the rule/template is bound to the current representor port:
> + *   - ingress -> RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT (dev->data->port_id)
> + *   - egress  -> MLX5_RTE_FLOW_ITEM_TYPE_TAG on REG_C_0 (tx vport tag),
> + *                skipped when the user already supplied an SQ item.

Does this comment header need to describe function parameters, return
values, and be in the Doxygen format (/** ... */) per the coding style
guidelines for non-static functions? The function flow_hw_adjust_pattern()
is called from multiple places but is not marked static.

> + *
> + * @param nt_flow
> + *   Selects between the two call paths that share this helper:
> + *     false -> pattern template creation (async API). The prepended item's
> + *              spec is left zeroed so mlx5dr matches any value; the live
> + *              port_id / tx-tag value is substituted later by
> + *              flow_hw_get_rule_items() at rule-create time.
> + *     true  -> sync (non-template) flow creation. The prepended item's spec
> + *              is filled immediately with the live values, and the flag is
> + *              forwarded to __flow_hw_pattern_validate() so that validation
> + *              paths gated on nt_flow (e.g. GENEVE_OPT TLV parser creation)
> + *              take the non-template branch.

[ ... ]

> +static const struct rte_flow_item *
> +flow_hw_adjust_pattern(struct rte_eth_dev *dev, const struct rte_flow_pattern_template_attr *attr,
> +		       bool nt_flow, const struct rte_flow_item *items, uint64_t *item_flags,
> +		       uint64_t *nb_items, struct rte_flow_item **copied_items,
> +		       struct rte_flow_error *error)

The line lengths in this function signature exceed 79 characters. Does
this comply with the coding style max line length requirement?

> +	if (!copied_items || !item_flags || !nb_items)
> +		return NULL;

When this function returns NULL due to NULL pointer arguments, is rte_errno
set appropriately? The callers appear to treat NULL returns as errors but
may expect error information.

> +
> +	if (nt_flow) {
> +		port.spec = &port_spec;
> +		tag_v.data = flow_hw_tx_tag_regc_value(dev);
> +	}

[ ... ]

> @@ -14272,7 +14329,6 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev *dev,
>  	struct rte_flow_hw *prfx_flow = NULL;
>  	const struct rte_flow_action *qrss = NULL;
>  	const struct rte_flow_action *mark = NULL;
> -	uint64_t item_flags = 0;
>  	uint64_t action_flags = mlx5_flow_hw_action_flags_get(actions, &qrss, &mark,
>  							 &encap_idx, &actions_n, error);

[ ... ]

> +	struct rte_flow_item *copied_items = NULL;
> +	const struct rte_flow_item *prepend_items;
> +	uint64_t orig_item_nb, item_flags;

The variables orig_item_nb and item_flags are declared without
initialization here. The patch notes mention zero-initialization is
required for item_flags. Is relying on flow_hw_adjust_pattern() to
initialize these values safe if that function changes in the future?

>  	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(copied_items);
> +		return 0;
> +	}

Good catch on the negative-to-uintptr_t cast bug. The cleanup of
copied_items is correct here.

>  	if (action_flags & MLX5_FLOW_ACTION_SAMPLE) {
> -		flow = mlx5_nta_sample_flow_list_create(dev, type, attr, items, actions,
> +		flow = mlx5_nta_sample_flow_list_create(dev, type, attr, prepend_items, actions,
>  							item_flags, action_flags, error);
> -		if (flow != NULL)
> +		if (flow != NULL) {
> +			mlx5_free(copied_items);
>  			return (uintptr_t)flow;
> +		}
>  		goto free;

Does this code free copied_items on all error paths? After the goto free
at the bottom of this block, does the cleanup path at the free: label also
call mlx5_free(copied_items)?

> @@ -14343,12 +14407,14 @@ 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(copied_items);
>  			return (uintptr_t)flow;
> +		}
>  		/* Fall Through to prefix flow creation. */

The comment says "Fall Through" but there is no explicit fallthrough
statement or attribute. Is this comment accurate for the control flow?

> @@ -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(copied_items);
>  	return 0;
>  }

Confirming the free: label does free copied_items. The cleanup appears
consistent across all paths.


More information about the test-report mailing list