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: fcea6f3da546 ("ice: Add stats and ethtool support") Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Gurucharan G <gurucharanx.g@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
de6acd1cdd
commit
1a0f25a52e
@ -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
|
||||
* @vsi: the VSI to be updated
|
||||
* @vsi_stats: the stats struct to be updated
|
||||
* @rings: rings to work on
|
||||
* @count: number of rings
|
||||
*/
|
||||
static void
|
||||
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi, struct ice_tx_ring **rings,
|
||||
u16 count)
|
||||
ice_update_vsi_tx_ring_stats(struct ice_vsi *vsi,
|
||||
struct rtnl_link_stats64 *vsi_stats,
|
||||
struct ice_tx_ring **rings, u16 count)
|
||||
{
|
||||
struct rtnl_link_stats64 *vsi_stats = &vsi->net_stats;
|
||||
u16 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,
|
||||
*/
|
||||
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;
|
||||
int i;
|
||||
|
||||
/* reset netdev stats */
|
||||
vsi_stats->tx_packets = 0;
|
||||
vsi_stats->tx_bytes = 0;
|
||||
vsi_stats->rx_packets = 0;
|
||||
vsi_stats->rx_bytes = 0;
|
||||
vsi_stats = kzalloc(sizeof(*vsi_stats), GFP_ATOMIC);
|
||||
if (!vsi_stats)
|
||||
return;
|
||||
|
||||
/* reset non-netdev (extended) stats */
|
||||
vsi->tx_restart = 0;
|
||||
@ -5981,7 +5980,8 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
|
||||
rcu_read_lock();
|
||||
|
||||
/* 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 */
|
||||
ice_for_each_rxq(vsi, i) {
|
||||
@ -5996,10 +5996,17 @@ static void ice_update_vsi_ring_stats(struct ice_vsi *vsi)
|
||||
|
||||
/* update XDP Tx rings counters */
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user