lkml.org 
[lkml]   [2021]   [Oct]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 62/83] gve: fix gve_get_stats()
    Date
    From: Eric Dumazet <edumazet@google.com>

    [ Upstream commit 2f57d4975fa027eabd35fdf23a49f8222ef3abf2 ]

    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 <edumazet@google.com>
    Cc: Catherine Sullivan <csully@google.com>
    Cc: Sagi Shahar <sagis@google.com>
    Cc: Jon Olson <jonolson@google.com>
    Cc: Willem de Bruijn <willemb@google.com>
    Cc: Luigi Rizzo <lrizzo@google.com>
    Cc: Jeroen de Borst <jeroendb@google.com>
    Cc: Tao Liu <xliutaox@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/ethernet/google/gve/gve_main.c | 13 +++++++++----
    1 file 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 22b2c6a8d08f..b658bf9b5399 100644
    --- a/drivers/net/ethernet/google/gve/gve_main.c
    +++ b/drivers/net/ethernet/google/gve/gve_main.c
    @@ -30,6 +30,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) {
    @@ -37,10 +38,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) {
    @@ -48,10 +51,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;
    }
    }
    }
    --
    2.33.0


    \
     
     \ /
      Last update: 2021-10-11 15:58    [W:7.911 / U:0.124 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site