aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <[email protected]>2021-10-05 17:30:30 -0700
committerDavid S. Miller <[email protected]>2021-10-06 15:11:51 +0100
commit2f57d4975fa027eabd35fdf23a49f8222ef3abf2 (patch)
tree241e39731a4a09e04fc447085c1eb5f080e166d6
parentd34367991933d28bd7331f67a759be9a8c474014 (diff)
gve: fix gve_get_stats()
gve_get_stats() can report wrong numbers if/when u64_stats_fetch_retry() returns true. What is needed here is to sample values in temporary variables, and only use them after each loop is ended. Fixes: f5cedc84a30d ("gve: Add transmit and receive support") Signed-off-by: Eric Dumazet <[email protected]> Cc: Catherine Sullivan <[email protected]> Cc: Sagi Shahar <[email protected]> Cc: Jon Olson <[email protected]> Cc: Willem de Bruijn <[email protected]> Cc: Luigi Rizzo <[email protected]> Cc: Jeroen de Borst <[email protected]> Cc: Tao Liu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
-rw-r--r--drivers/net/ethernet/google/gve/gve_main.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 29c5f994f92e..1b49e9feacac 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
{
struct gve_priv *priv = netdev_priv(dev);
unsigned int start;
+ u64 packets, bytes;
int ring;
if (priv->rx) {
@@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
do {
start =
u64_stats_fetch_begin(&priv->rx[ring].statss);
- s->rx_packets += priv->rx[ring].rpackets;
- s->rx_bytes += priv->rx[ring].rbytes;
+ packets = priv->rx[ring].rpackets;
+ bytes = priv->rx[ring].rbytes;
} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
start));
+ s->rx_packets += packets;
+ s->rx_bytes += bytes;
}
}
if (priv->tx) {
@@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
do {
start =
u64_stats_fetch_begin(&priv->tx[ring].statss);
- s->tx_packets += priv->tx[ring].pkt_done;
- s->tx_bytes += priv->tx[ring].bytes_done;
+ packets = priv->tx[ring].pkt_done;
+ bytes = priv->tx[ring].bytes_done;
} while (u64_stats_fetch_retry(&priv->tx[ring].statss,
start));
+ s->tx_packets += packets;
+ s->tx_bytes += bytes;
}
}
}