Commit 1a0f25a5 authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Tony Nguyen

ice: safer stats processing

The driver was zeroing live stats that could be fetched by
ndo_get_stats64 at any time. This could result in inconsistent
statistics, and the telltale sign was when reading stats frequently from
/proc/net/dev, the stats would go backwards.

Fix by collecting stats into a local, and delaying when we write to the
structure so it's not incremental.

Fixes: fcea6f3d ("ice: Add stats and ethtool support")
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: default avatarGurucharan G <gurucharanx.g@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent de6acd1c
...@@ -5930,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st ...@@ -5930,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st
/** /**
* ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters * ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters
* @vsi: the VSI to be updated * @vsi: the VSI to be updated
* @vsi_stats: the stats struct to be updated
* @rings: rings to work on * @rings: rings to work on
* @count: number of rings * @count: number of rings
*/ */
static void static void
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi,
u16 count) struct rtnl_link_stats64 *vsi_stats,
struct ice_tx_ring **rings, u16 count)
{ {
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
u16 i; u16 i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -5961,15 +5962,13 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings, ...@@ -5961,15 +5962,13 @@ ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings,
*/ */
static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
{ {
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats; struct rtnl_link_stats64 *vsi_stats;
u64 pkts, bytes; u64 pkts, bytes;
int i; int i;
/* reset netdev stats */ vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC);
vsi_stats->tx_packets = 0; if (!vsi_stats)
vsi_stats->tx_bytes = 0; return;
vsi_stats->rx_packets = 0;
vsi_stats->rx_bytes = 0;
/* reset non-netdev (extended) stats */ /* reset non-netdev (extended) stats */
vsi->tx_restart = 0; vsi->tx_restart = 0;
...@@ -5981,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) ...@@ -5981,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
rcu_read_lock(); rcu_read_lock();
/* update Tx rings counters */ /* update Tx rings counters */
ice_update_vsi_tx_ring_stats(vsi, vsi->tx_rings, vsi->num_txq); ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->tx_rings,
vsi->num_txq);
/* update Rx rings counters */ /* update Rx rings counters */
ice_for_each_rxq(vsi, i) { ice_for_each_rxq(vsi, i) {
...@@ -5996,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi) ...@@ -5996,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
/* update XDP Tx rings counters */ /* update XDP Tx rings counters */
if (ice_is_xdp_ena_vsi(vsi)) if (ice_is_xdp_ena_vsi(vsi))
ice_update_vsi_tx_ring_stats(vsi, vsi->xdp_rings, ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->xdp_rings,
vsi->num_xdp_txq); vsi->num_xdp_txq);
rcu_read_unlock(); rcu_read_unlock();
vsi->net_stats.tx_packets = vsi_stats->tx_packets;
vsi->net_stats.tx_bytes = vsi_stats->tx_bytes;
vsi->net_stats.rx_packets = vsi_stats->rx_packets;
vsi->net_stats.rx_bytes = vsi_stats->rx_bytes;
kfree(vsi_stats);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment