Skip to content

Commit 1a0f25a

Browse files
jbrandebanguy11
authored andcommitted
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: fcea6f3 ("ice: Add stats and ethtool support") Signed-off-by: Jesse Brandeburg <[email protected]> Tested-by: Gurucharan G <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent de6acd1 commit 1a0f25a

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5930,14 +5930,15 @@ ice_fetch_u64_stats_per_ring(struct u64_stats_sync *syncp, struct ice_q_stats st
59305930
/**
59315931
* ice_update_vsi_tx_ring_stats - Update VSI Tx ring stats counters
59325932
* @vsi: the VSI to be updated
5933+
* @vsi_stats: the stats struct to be updated
59335934
* @rings: rings to work on
59345935
* @count: number of rings
59355936
*/
59365937
static void
5937-
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings,
5938-
u16 count)
5938+
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi,
5939+
struct rtnl_link_stats64 *vsi_stats,
5940+
struct ice_tx_ring **rings, u16 count)
59395941
{
5940-
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
59415942
u16 i;
59425943

59435944
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,
59615962
*/
59625963
static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
59635964
{
5964-
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
5965+
struct rtnl_link_stats64 *vsi_stats;
59655966
u64 pkts, bytes;
59665967
int i;
59675968

5968-
/* reset netdev stats */
5969-
vsi_stats->tx_packets = 0;
5970-
vsi_stats->tx_bytes = 0;
5971-
vsi_stats->rx_packets = 0;
5972-
vsi_stats->rx_bytes = 0;
5969+
vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC);
5970+
if (!vsi_stats)
5971+
return;
59735972

59745973
/* reset non-netdev (extended) stats */
59755974
vsi->tx_restart = 0;
@@ -5981,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
59815980
rcu_read_lock();
59825981

59835982
/* update Tx rings counters */
5984-
ice_update_vsi_tx_ring_stats(vsi, vsi->tx_rings, vsi->num_txq);
5983+
ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->tx_rings,
5984+
vsi->num_txq);
59855985

59865986
/* update Rx rings counters */
59875987
ice_for_each_rxq(vsi, i) {
@@ -5996,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
59965996

59975997
/* update XDP Tx rings counters */
59985998
if (ice_is_xdp_ena_vsi(vsi))
5999-
ice_update_vsi_tx_ring_stats(vsi, vsi->xdp_rings,
5999+
ice_update_vsi_tx_ring_stats(vsi, vsi_stats, vsi->xdp_rings,
60006000
vsi->num_xdp_txq);
60016001

60026002
rcu_read_unlock();
6003+
6004+
vsi->net_stats.tx_packets = vsi_stats->tx_packets;
6005+
vsi->net_stats.tx_bytes = vsi_stats->tx_bytes;
6006+
vsi->net_stats.rx_packets = vsi_stats->rx_packets;
6007+
vsi->net_stats.rx_bytes = vsi_stats->rx_bytes;
6008+
6009+
kfree(vsi_stats);
60036010
}
60046011

60056012
/**

0 commit comments

Comments
 (0)