summaryrefslogtreecommitdiffstats
path: root/dpdk/dpdk-17.02_patches/0003-dpdk-dev-2-2-net-mlx5-fix-extended-statistics-wrong-number.patch
blob: 05c2e8df82c95d848df27296232ce1e3211c28e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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);
 }