| diff --git a/drivers/net/mlx5/mlx5_stats.c b/drivers/net/mlx5/mlx5_stats.c |
| index 0c80e4f..60ffbaa 100644 |
| --- a/drivers/net/mlx5/mlx5_stats.c |
| +++ b/drivers/net/mlx5/mlx5_stats.c |
| @@ -166,6 +166,29 @@ struct mlx5_counter_ctrl { |
| } |
| |
| /** |
| + * Query the number of statistics provided by ETHTOOL. |
| + * |
| + * @param priv |
| + * Pointer to private structure. |
| + * |
| + * @return |
| + * Number of statistics on success, -1 on error. |
| + */ |
| +static int |
| +priv_ethtool_get_stats_n(struct priv *priv) { |
| + struct ethtool_drvinfo drvinfo; |
| + struct ifreq ifr; |
| + |
| + drvinfo.cmd = ETHTOOL_GDRVINFO; |
| + ifr.ifr_data = (caddr_t)&drvinfo; |
| + if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) { |
| + WARN("unable to query number of statistics"); |
| + return -1; |
| + } |
| + return drvinfo.n_stats; |
| +} |
| + |
| +/** |
| * Init the structures to read device counters. |
| * |
| * @param priv |
| @@ -178,19 +201,11 @@ struct mlx5_counter_ctrl { |
| unsigned int i; |
| unsigned int j; |
| struct ifreq ifr; |
| - struct ethtool_drvinfo drvinfo; |
| struct ethtool_gstrings *strings = NULL; |
| unsigned int dev_stats_n; |
| unsigned int str_sz; |
| |
| - /* How many statistics are available. */ |
| - drvinfo.cmd = ETHTOOL_GDRVINFO; |
| - ifr.ifr_data = (caddr_t)&drvinfo; |
| - if (priv_ifreq(priv, SIOCETHTOOL, &ifr) != 0) { |
| - WARN("unable to get driver info"); |
| - return; |
| - } |
| - dev_stats_n = drvinfo.n_stats; |
| + dev_stats_n = priv_ethtool_get_stats_n(priv); |
| if (dev_stats_n < 1) { |
| WARN("no extended statistics available"); |
| return; |
| @@ -410,7 +425,15 @@ struct mlx5_counter_ctrl { |
| int ret = xstats_n; |
| |
| if (n >= xstats_n && stats) { |
| + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
| + int stats_n; |
| + |
| priv_lock(priv); |
| + stats_n = priv_ethtool_get_stats_n(priv); |
| + if (stats_n < 0) |
| + return -1; |
| + if (xstats_ctrl->stats_n != stats_n) |
| + priv_xstats_init(priv); |
| ret = priv_xstats_get(priv, stats); |
| priv_unlock(priv); |
| } |
| @@ -427,8 +450,15 @@ struct mlx5_counter_ctrl { |
| mlx5_xstats_reset(struct rte_eth_dev *dev) |
| { |
| struct priv *priv = mlx5_get_priv(dev); |
| + struct mlx5_xstats_ctrl *xstats_ctrl = &priv->xstats_ctrl; |
| + int stats_n; |
| |
| priv_lock(priv); |
| + stats_n = priv_ethtool_get_stats_n(priv); |
| + if (stats_n < 0) |
| + return; |
| + if (xstats_ctrl->stats_n != stats_n) |
| + priv_xstats_init(priv); |
| priv_xstats_reset(priv); |
| priv_unlock(priv); |
| } |