diff options
author | Brice Goglin <brice@myri.com> | 2009-04-15 22:23:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-16 21:00:43 -0400 |
commit | 590818250684d18bb0e30c45d79971dcdff96ad0 (patch) | |
tree | 74569b7dc4061819495b00ac4321a30f78791dad /drivers | |
parent | a54bfa40fd16aeb90bc556189221576f746f8567 (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')
-rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 7 |
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 | ||
364 | static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); | ||
365 | |||
364 | static int | 366 | static int |
365 | myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, | 367 | myri10ge_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); |