|SUCCESS| [v2] net/mlx5: use port index as representor index
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Mon May 25 13:42:41 CEST 2026
Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/164356
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-05-25
I've analyzed the patch against the DPDK coding standards and contribution guidelines. Here's my review:
git sha: 20260525091733.558838-1-dsosnowski at nvidia.com
Author: Dariusz Sosnowski <dsosnowski at nvidia.com>
Subject: [PATCH v2] net/mlx5: use port index as representor index
This patch changes the mlx5 driver logic for handling representor IDs
by dynamically assigning representor_id values to each probed
representor instead of using a static encoding scheme.
> diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
> index 0fc721592b..5305523c1b 100644
> --- a/drivers/net/mlx5/linux/mlx5_os.c
> +++ b/drivers/net/mlx5/linux/mlx5_os.c
> @@ -1677,9 +1677,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
> err = ENOMEM;
> goto error;
> }
> + priv->port_info.type = spawn->info.name_type;
> + priv->port_info.ctrl_num = spawn->info.ctrl_num;
> + priv->port_info.pf_num = spawn->info.pf_num;
> + priv->port_info.port_num = spawn->info.port_name;
> if (priv->representor) {
> eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
> - eth_dev->data->representor_id = priv->representor_id;
> + eth_dev->data->representor_id = eth_dev->data->port_id;
This line assigns port_id to representor_id without verifying that
port_id has been initialized at this point in mlx5_dev_spawn(). Has
port_id been assigned before this code is reached? Should this
assignment be deferred until after port registration?
[ ... ]
> diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> index 49a0c03544..23803b450b 100644
> --- a/drivers/net/mlx5/mlx5.h
> +++ b/drivers/net/mlx5/mlx5.h
> @@ -1984,6 +1984,24 @@ struct mlx5_quota_ctx {
> struct mlx5_indexed_pool *quota_ipool; /* Manage quota objects */
> };
>
> +/* Stores info parsed from phys_port_name related to given DPDK port. */
> +struct mlx5_representor_info {
> + enum mlx5_nl_phys_port_name_type type;
> + /* PCI controller index. 0 if no controller was reported in phys_port_name. */
DPDK coding style requires that multi-line comments follow the format:
/*
* First line.
* Second line.
*/
The single-line comment on a field declaration should be on a separate
line or follow the closing brace format.
> + int32_t ctrl_num;
> + /* PF index. */
> + int32_t pf_num;
> + /*
> + * Representor number:
> + *
> + * - For VF/SF - VF/SF index.
> + * - For PFHPF - -1.
> + * - For uplink - physical port index.
> + * - For others - VF representor is assumed, so VF index.
> + */
> + int32_t port_num;
> +};
[ ... ]
> diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
> index a29cdeeb50..e14b7f148b 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
[ ... ]
> +static void
> +mlx5_representor_info_fill_one(struct mlx5_priv *priv,
> + struct rte_eth_representor_info *info)
> +{
> + struct rte_eth_representor_range *range;
> + unsigned int count;
> +
> + count = mlx5_representor_info_count_one(priv);
> + if (count == 0)
> + return;
> +
> + if (info->nb_ranges + count > info->nb_ranges_alloc) {
> + DRV_LOG(ERR, "port %u representor info already full", priv->dev_data->port_id);
> + return;
> + }
When this overflow condition occurs in mlx5_representor_info_fill_one(),
does the error get propagated back to the caller? The function returns
void, so after logging the error the function simply returns. Should the
caller check for partial filling of info->ranges, or should this
function return an error code?
> +
> + range = &info->ranges[info->nb_ranges];
> +
> + switch (priv->port_info.type) {
> + case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
> + range->type = RTE_ETH_REPRESENTOR_PF;
> + range->controller = priv->port_info.ctrl_num;
> + range->pf = priv->port_info.port_num;
> + range->id_base = priv->dev_data->port_id;
> + range->id_end = range->id_base;
> + snprintf(range->name, sizeof(range->name), "pf%d", range->pf);
> + break;
> + case MLX5_PHYS_PORT_NAME_TYPE_PFSF:
> + /* Secondly, fill in SF variant. */
> + range->type = RTE_ETH_REPRESENTOR_SF;
> + range->controller = priv->port_info.ctrl_num;
> + range->pf = priv->port_info.pf_num;
> + range->sf = priv->port_info.port_num;
> + range->id_base = priv->dev_data->port_id;
> + range->id_end = range->id_base;
> + snprintf(range->name, sizeof(range->name), "pf%dsf", range->pf);
> + break;
> + case MLX5_PHYS_PORT_NAME_TYPE_PFHPF:
> + /*
> + * Host PF can be probed either through VF(0xffff) or SF(0xffff).
> + * Firstly fill in VF variant.
> + */
> + range->type = RTE_ETH_REPRESENTOR_VF;
> + range->controller = priv->port_info.ctrl_num;
> + range->pf = priv->port_info.pf_num;
> + range->vf = UINT16_MAX;
> + range->id_base = priv->dev_data->port_id;
> + range->id_end = range->id_base;
> + snprintf(range->name, sizeof(range->name), "pf%dvf", range->pf);
> +
> + /* Move the SF variant. */
> + range++;
After incrementing range, does this pointer arithmetic stay within the
bounds of info->ranges[]? The bounds check at the start of the function
verifies info->nb_ranges + count is within bounds, but then range is
incremented before filling the second entry. If info->nb_ranges_alloc
equals info->nb_ranges + count exactly, does this overflow
info->ranges[]?
> +
> + /* Fill in SF variant. */
> + range->type = RTE_ETH_REPRESENTOR_SF;
> + range->controller = priv->port_info.ctrl_num;
> + range->pf = priv->port_info.pf_num;
> + range->sf = UINT16_MAX;
> + range->id_base = priv->dev_data->port_id;
> + range->id_end = range->id_base;
> + snprintf(range->name, sizeof(range->name), "pf%dsf", range->pf);
> + break;
[ ... ]
More information about the test-report
mailing list