aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_ethtool.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-10-20 19:00:04 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-21 06:55:22 -0400
commitde1036b1cea147c5049c65f5bd26fb451f1624cd (patch)
tree35406b956bd4d39d73becf2bb28ea37c6e040e27 /drivers/net/ixgbe/ixgbe_ethtool.c
parent3a338cbb8bb46a6b86f4dca54bf73b9c78751659 (diff)
ixgbe: fix stats handling
Current ixgbe stats have following problems : - Not 64 bit safe (on 32bit arches) - Not safe in ixgbe_clean_rx_irq() : All cpus dirty a common location (netdev->stats.rx_bytes & netdev->stats.rx_packets) without proper synchronization. This slow down a bit multiqueue operations, and possibly miss some updates. Fixes : Implement ndo_get_stats64() method to provide accurate 64bit rx|tx bytes/packets counters, using 64bit safe infrastructure. ixgbe_get_ethtool_stats() also use this infrastructure to provide 64bit safe counters. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Acked-by: Don Skidmore <donald.c.skidmore@intel.com> Tested-by: Stephen Ko <stephen.s.ko@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_ethtool.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index dbfd62fd40e..3dc731c22ff 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -999,12 +999,11 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
999 struct ethtool_stats *stats, u64 *data) 999 struct ethtool_stats *stats, u64 *data)
1000{ 1000{
1001 struct ixgbe_adapter *adapter = netdev_priv(netdev); 1001 struct ixgbe_adapter *adapter = netdev_priv(netdev);
1002 u64 *queue_stat;
1003 int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
1004 struct rtnl_link_stats64 temp; 1002 struct rtnl_link_stats64 temp;
1005 const struct rtnl_link_stats64 *net_stats; 1003 const struct rtnl_link_stats64 *net_stats;
1006 int j, k; 1004 unsigned int start;
1007 int i; 1005 struct ixgbe_ring *ring;
1006 int i, j;
1008 char *p = NULL; 1007 char *p = NULL;
1009 1008
1010 ixgbe_update_stats(adapter); 1009 ixgbe_update_stats(adapter);
@@ -1025,16 +1024,22 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
1025 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1024 sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
1026 } 1025 }
1027 for (j = 0; j < adapter->num_tx_queues; j++) { 1026 for (j = 0; j < adapter->num_tx_queues; j++) {
1028 queue_stat = (u64 *)&adapter->tx_ring[j]->stats; 1027 ring = adapter->tx_ring[j];
1029 for (k = 0; k < stat_count; k++) 1028 do {
1030 data[i + k] = queue_stat[k]; 1029 start = u64_stats_fetch_begin_bh(&ring->syncp);
1031 i += k; 1030 data[i] = ring->stats.packets;
1031 data[i+1] = ring->stats.bytes;
1032 } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
1033 i += 2;
1032 } 1034 }
1033 for (j = 0; j < adapter->num_rx_queues; j++) { 1035 for (j = 0; j < adapter->num_rx_queues; j++) {
1034 queue_stat = (u64 *)&adapter->rx_ring[j]->stats; 1036 ring = adapter->rx_ring[j];
1035 for (k = 0; k < stat_count; k++) 1037 do {
1036 data[i + k] = queue_stat[k]; 1038 start = u64_stats_fetch_begin_bh(&ring->syncp);
1037 i += k; 1039 data[i] = ring->stats.packets;
1040 data[i+1] = ring->stats.bytes;
1041 } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
1042 i += 2;
1038 } 1043 }
1039 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { 1044 if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
1040 for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) { 1045 for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) {