aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/myri10ge
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2009-04-15 22:23:56 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-16 21:00:43 -0400
commit590818250684d18bb0e30c45d79971dcdff96ad0 (patch)
tree74569b7dc4061819495b00ac4321a30f78791dad /drivers/net/myri10ge
parenta54bfa40fd16aeb90bc556189221576f746f8567 (diff)
myri10ge: force stats update in ethtool gstats
Force a statistics update when our ethtool gstats routine is called. Otherwise, ethtool will continue to read stale stats until something forces an update by reading /proc/net/dev This requires putting a lock around the stats update to guard against 2 threads (one via ethtool, and one via procfs) updating the stats at once. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/myri10ge')
-rw-r--r--drivers/net/myri10ge/myri10ge.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f2c4a665e93f..a833cdd85466 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -361,6 +361,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p)
361 __raw_writel((__force __u32) val, (__force void __iomem *)p); 361 __raw_writel((__force __u32) val, (__force void __iomem *)p);
362} 362}
363 363
364static struct net_device_stats *myri10ge_get_stats(struct net_device *dev);
365
364static int 366static int
365myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, 367myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
366 struct myri10ge_cmd *data, int atomic) 368 struct myri10ge_cmd *data, int atomic)
@@ -1803,6 +1805,8 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
1803 int slice; 1805 int slice;
1804 int i; 1806 int i;
1805 1807
1808 /* force stats update */
1809 (void)myri10ge_get_stats(netdev);
1806 for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) 1810 for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
1807 data[i] = ((unsigned long *)&mgp->stats)[i]; 1811 data[i] = ((unsigned long *)&mgp->stats)[i];
1808 1812
@@ -2969,6 +2973,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
2969 struct net_device_stats *stats = &mgp->stats; 2973 struct net_device_stats *stats = &mgp->stats;
2970 int i; 2974 int i;
2971 2975
2976 spin_lock(&mgp->stats_lock);
2972 memset(stats, 0, sizeof(*stats)); 2977 memset(stats, 0, sizeof(*stats));
2973 for (i = 0; i < mgp->num_slices; i++) { 2978 for (i = 0; i < mgp->num_slices; i++) {
2974 slice_stats = &mgp->ss[i].stats; 2979 slice_stats = &mgp->ss[i].stats;
@@ -2979,6 +2984,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
2979 stats->rx_dropped += slice_stats->rx_dropped; 2984 stats->rx_dropped += slice_stats->rx_dropped;
2980 stats->tx_dropped += slice_stats->tx_dropped; 2985 stats->tx_dropped += slice_stats->tx_dropped;
2981 } 2986 }
2987 spin_unlock(&mgp->stats_lock);
2982 return stats; 2988 return stats;
2983} 2989}
2984 2990
@@ -3902,6 +3908,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3902 setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, 3908 setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
3903 (unsigned long)mgp); 3909 (unsigned long)mgp);
3904 3910
3911 spin_lock_init(&mgp->stats_lock);
3905 SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); 3912 SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
3906 INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog); 3913 INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
3907 status = register_netdev(netdev); 3914 status = register_netdev(netdev);