aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-07-07 17:58:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-07 17:58:56 -0400
commit28172739f0a276eb8d6ca917b3974c2edb036da3 (patch)
treeb1dc00cfa20c209992e247c6f73601f609f9ca3b /drivers/net/bonding/bond_main.c
parent217d32dc5f299c483ca0d3c8cc6811c72c0339c4 (diff)
net: fix 64 bit counters on 32 bit arches
There is a small possibility that a reader gets incorrect values on 32 bit arches. SNMP applications could catch incorrect counters when a 32bit high part is changed by another stats consumer/provider. One way to solve this is to add a rtnl_link_stats64 param to all ndo_get_stats64() methods, and also add such a parameter to dev_get_stats(). Rule is that we are not allowed to use dev->stats64 as a temporary storage for 64bit stats, but a caller provided area (usually on stack) Old drivers (only providing get_stats() method) need no changes. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c64
1 files changed, 31 insertions, 33 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a95a41b74b4..9bb9bfa225b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3804,51 +3804,49 @@ static int bond_close(struct net_device *bond_dev)
3804 return 0; 3804 return 0;
3805} 3805}
3806 3806
3807static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev) 3807static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
3808 struct rtnl_link_stats64 *stats)
3808{ 3809{
3809 struct bonding *bond = netdev_priv(bond_dev); 3810 struct bonding *bond = netdev_priv(bond_dev);
3810 struct rtnl_link_stats64 *stats = &bond_dev->stats64; 3811 struct rtnl_link_stats64 temp;
3811 struct rtnl_link_stats64 local_stats;
3812 struct slave *slave; 3812 struct slave *slave;
3813 int i; 3813 int i;
3814 3814
3815 memset(&local_stats, 0, sizeof(local_stats)); 3815 memset(stats, 0, sizeof(*stats));
3816 3816
3817 read_lock_bh(&bond->lock); 3817 read_lock_bh(&bond->lock);
3818 3818
3819 bond_for_each_slave(bond, slave, i) { 3819 bond_for_each_slave(bond, slave, i) {
3820 const struct rtnl_link_stats64 *sstats = 3820 const struct rtnl_link_stats64 *sstats =
3821 dev_get_stats(slave->dev); 3821 dev_get_stats(slave->dev, &temp);
3822 3822
3823 local_stats.rx_packets += sstats->rx_packets; 3823 stats->rx_packets += sstats->rx_packets;
3824 local_stats.rx_bytes += sstats->rx_bytes; 3824 stats->rx_bytes += sstats->rx_bytes;
3825 local_stats.rx_errors += sstats->rx_errors; 3825 stats->rx_errors += sstats->rx_errors;
3826 local_stats.rx_dropped += sstats->rx_dropped; 3826 stats->rx_dropped += sstats->rx_dropped;
3827 3827
3828 local_stats.tx_packets += sstats->tx_packets; 3828 stats->tx_packets += sstats->tx_packets;
3829 local_stats.tx_bytes += sstats->tx_bytes; 3829 stats->tx_bytes += sstats->tx_bytes;
3830 local_stats.tx_errors += sstats->tx_errors; 3830 stats->tx_errors += sstats->tx_errors;
3831 local_stats.tx_dropped += sstats->tx_dropped; 3831 stats->tx_dropped += sstats->tx_dropped;
3832 3832
3833 local_stats.multicast += sstats->multicast; 3833 stats->multicast += sstats->multicast;
3834 local_stats.collisions += sstats->collisions; 3834 stats->collisions += sstats->collisions;
3835 3835
3836 local_stats.rx_length_errors += sstats->rx_length_errors; 3836 stats->rx_length_errors += sstats->rx_length_errors;
3837 local_stats.rx_over_errors += sstats->rx_over_errors; 3837 stats->rx_over_errors += sstats->rx_over_errors;
3838 local_stats.rx_crc_errors += sstats->rx_crc_errors; 3838 stats->rx_crc_errors += sstats->rx_crc_errors;
3839 local_stats.rx_frame_errors += sstats->rx_frame_errors; 3839 stats->rx_frame_errors += sstats->rx_frame_errors;
3840 local_stats.rx_fifo_errors += sstats->rx_fifo_errors; 3840 stats->rx_fifo_errors += sstats->rx_fifo_errors;
3841 local_stats.rx_missed_errors += sstats->rx_missed_errors; 3841 stats->rx_missed_errors += sstats->rx_missed_errors;
3842 3842
3843 local_stats.tx_aborted_errors += sstats->tx_aborted_errors; 3843 stats->tx_aborted_errors += sstats->tx_aborted_errors;
3844 local_stats.tx_carrier_errors += sstats->tx_carrier_errors; 3844 stats->tx_carrier_errors += sstats->tx_carrier_errors;
3845 local_stats.tx_fifo_errors += sstats->tx_fifo_errors; 3845 stats->tx_fifo_errors += sstats->tx_fifo_errors;
3846 local_stats.tx_heartbeat_errors += sstats->tx_heartbeat_errors; 3846 stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors;
3847 local_stats.tx_window_errors += sstats->tx_window_errors; 3847 stats->tx_window_errors += sstats->tx_window_errors;
3848 } 3848 }
3849 3849
3850 memcpy(stats, &local_stats, sizeof(struct net_device_stats));
3851
3852 read_unlock_bh(&bond->lock); 3850 read_unlock_bh(&bond->lock);
3853 3851
3854 return stats; 3852 return stats;