|SUCCESS| net/mlx5: add hardware query for basic stats

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Fri Apr 17 03:01:13 CEST 2026


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

_AI Code Review_

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

Reviewing patch: net/mlx5: add hardware query for basic stats

Author: Rayane Boussanni <rboussanni at gmail.com>

Subject: [PATCH] net/mlx5: add hardware query for basic stats

This patch adds hardware counter querying for basic statistics when
MLX5_PMD_SOFT_COUNTERS is not defined, replacing the previous FIXME
comments with actual implementation.

> diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c
> index 5cd3e303cc..198f231559 100644
> --- a/drivers/net/mlx5/mlx5_stats.c
> +++ b/drivers/net/mlx5/mlx5_stats.c
> @@ -280,7 +280,46 @@ mlx5_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
>  		tmp.imissed = stats_ctrl->imissed;
>  	}
>  #ifndef MLX5_PMD_SOFT_COUNTERS
> -	/* FIXME: retrieve and add hardware counters. */
> +	{
> +		uint64_t counters[MLX5_MAX_XSTATS];
> +		struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
> +		bool bond_master = (priv->master && priv->pf_bond >= 0);
> +
> +		ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
> +		if (ret) {
> +			DRV_LOG(WARNING, "port %u unable to read device counters",
> +				dev->data->port_id);
> +			return ret;
> +		}
> +		for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i) {

Does the variable 'i' overflow when xstats_ctrl->mlx5_stats_n exceeds
MLX5_MAX_XSTATS? The counters array is sized to MLX5_MAX_XSTATS, but
there is no bounds checking before accessing counters[i] and
xstats_ctrl->base[i].

> +			const char *name = xstats_ctrl->info[i].dpdk_name;
> +			uint64_t val = (counters[i] - xstats_ctrl->base[i]);
> +
> +			if (!strcmp(name, "rx_unicast_packets") ||
> +			    !strcmp(name, "rx_multicast_packets") ||
> +			    !strcmp(name, "rx_broadcast_packets"))
> +				tmp.ipackets += val;
> +			else if (!strcmp(name, "rx_unicast_bytes") ||
> +				 !strcmp(name, "rx_multicast_bytes") ||
> +				 !strcmp(name, "rx_broadcast_bytes"))
> +				tmp.ibytes += val;
> +			else if (!strcmp(name, "tx_unicast_packets") ||
> +				 !strcmp(name, "tx_multicast_packets") ||
> +				 !strcmp(name, "tx_broadcast_packets"))
> +				tmp.opackets += val;
> +			else if (!strcmp(name, "tx_unicast_bytes") ||
> +				 !strcmp(name, "tx_multicast_bytes") ||
> +				 !strcmp(name, "tx_broadcast_bytes"))
> +				tmp.obytes += val;
> +			else if (!strcmp(name, "rx_wqe_errors") ||
> +				 !strcmp(name, "rx_phy_crc_errors") ||
> +				 !strcmp(name, "rx_phy_in_range_len_errors") ||
> +				 !strcmp(name, "rx_phy_symbol_errors"))
> +				tmp.ierrors += val;
> +			else if (!strcmp(name, "tx_phy_errors"))
> +				tmp.oerrors += val;

Can xstats_ctrl->info[i].dpdk_name be NULL? If so, does this code
properly handle that case before calling strcmp?

[ ... ]

> @@ -319,7 +358,21 @@ mlx5_stats_reset(struct rte_eth_dev *dev)
>  	mlx5_os_read_dev_stat(priv, "out_of_buffer", &stats_ctrl->imissed_base);
>  	stats_ctrl->imissed = 0;
>  #ifndef MLX5_PMD_SOFT_COUNTERS
> -	/* FIXME: reset hardware counters. */
> +	{
> +		uint64_t counters[MLX5_MAX_XSTATS];
> +		struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl;
> +		bool bond_master = (priv->master && priv->pf_bond >= 0);
> +		int ret;
> +
> +		ret = mlx5_os_read_dev_counters(dev, bond_master, counters);
> +		if (ret) {
> +			DRV_LOG(WARNING, "port %u unable to read device counters",
> +				dev->data->port_id);
> +			return ret;
> +		}
> +		for (i = 0; i != xstats_ctrl->mlx5_stats_n; ++i)
> +			xstats_ctrl->base[i] = counters[i];

Same question as above: does this loop have proper bounds checking to
ensure mlx5_stats_n does not exceed MLX5_MAX_XSTATS before accessing
counters[i]?

> +	}
>  #endif
>  
>  	return 0;


More information about the test-report mailing list