diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-07-07 17:58:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-07 17:58:56 -0400 |
commit | 28172739f0a276eb8d6ca917b3974c2edb036da3 (patch) | |
tree | b1dc00cfa20c209992e247c6f73601f609f9ca3b /drivers/net/sfc | |
parent | 217d32dc5f299c483ca0d3c8cc6811c72c0339c4 (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/sfc')
-rw-r--r-- | drivers/net/sfc/efx.c | 3 | ||||
-rw-r--r-- | drivers/net/sfc/ethtool.c | 3 |
2 files changed, 3 insertions, 3 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 35b3f2922e5c..ba674c5ca29e 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -1533,11 +1533,10 @@ static int efx_net_stop(struct net_device *net_dev) | |||
1533 | } | 1533 | } |
1534 | 1534 | ||
1535 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ | 1535 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
1536 | static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev) | 1536 | static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats) |
1537 | { | 1537 | { |
1538 | struct efx_nic *efx = netdev_priv(net_dev); | 1538 | struct efx_nic *efx = netdev_priv(net_dev); |
1539 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | 1539 | struct efx_mac_stats *mac_stats = &efx->mac_stats; |
1540 | struct rtnl_link_stats64 *stats = &net_dev->stats64; | ||
1541 | 1540 | ||
1542 | spin_lock_bh(&efx->stats_lock); | 1541 | spin_lock_bh(&efx->stats_lock); |
1543 | efx->type->update_stats(efx); | 1542 | efx->type->update_stats(efx); |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 3b8b0a062749..fd19d6ab97a2 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -469,12 +469,13 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, | |||
469 | struct efx_mac_stats *mac_stats = &efx->mac_stats; | 469 | struct efx_mac_stats *mac_stats = &efx->mac_stats; |
470 | struct efx_ethtool_stat *stat; | 470 | struct efx_ethtool_stat *stat; |
471 | struct efx_channel *channel; | 471 | struct efx_channel *channel; |
472 | struct rtnl_link_stats64 temp; | ||
472 | int i; | 473 | int i; |
473 | 474 | ||
474 | EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); | 475 | EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); |
475 | 476 | ||
476 | /* Update MAC and NIC statistics */ | 477 | /* Update MAC and NIC statistics */ |
477 | dev_get_stats(net_dev); | 478 | dev_get_stats(net_dev, &temp); |
478 | 479 | ||
479 | /* Fill detailed statistics buffer */ | 480 | /* Fill detailed statistics buffer */ |
480 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { | 481 | for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { |