aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
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/sfc
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/sfc')
-rw-r--r--drivers/net/sfc/efx.c3
-rw-r--r--drivers/net/sfc/ethtool.c3
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. */
1536static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev) 1536static 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++) {