diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2009-01-29 13:00:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-30 17:06:33 -0500 |
commit | 1974cc205e63cec4a17a6b3fca31fa4240ded77e (patch) | |
tree | d658cbc56064d86f3f57e786b4ebcf33346188bd /drivers/net/sfc/efx.c | |
parent | af4ad9bca0c4039355b20d760b4fd39afa48c59d (diff) |
sfc: Replace stats_enabled flag with a disable count
Currently we use a spin-lock to serialise statistics fetches and also
to inhibit them for short periods of time, plus a flag to
enable/disable statistics fetches for longer periods of time, during
online reset. This was apparently insufficient to deal with the several
reasons for stats being disabled.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index b0e53087bda0..ab0e09bf154d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -685,7 +685,7 @@ static int efx_init_port(struct efx_nic *efx) | |||
685 | efx->mac_op->reconfigure(efx); | 685 | efx->mac_op->reconfigure(efx); |
686 | 686 | ||
687 | efx->port_initialized = true; | 687 | efx->port_initialized = true; |
688 | efx->stats_enabled = true; | 688 | efx_stats_enable(efx); |
689 | return 0; | 689 | return 0; |
690 | 690 | ||
691 | fail: | 691 | fail: |
@@ -734,6 +734,7 @@ static void efx_fini_port(struct efx_nic *efx) | |||
734 | if (!efx->port_initialized) | 734 | if (!efx->port_initialized) |
735 | return; | 735 | return; |
736 | 736 | ||
737 | efx_stats_disable(efx); | ||
737 | efx->phy_op->fini(efx); | 738 | efx->phy_op->fini(efx); |
738 | efx->port_initialized = false; | 739 | efx->port_initialized = false; |
739 | 740 | ||
@@ -1360,6 +1361,20 @@ static int efx_net_stop(struct net_device *net_dev) | |||
1360 | return 0; | 1361 | return 0; |
1361 | } | 1362 | } |
1362 | 1363 | ||
1364 | void efx_stats_disable(struct efx_nic *efx) | ||
1365 | { | ||
1366 | spin_lock(&efx->stats_lock); | ||
1367 | ++efx->stats_disable_count; | ||
1368 | spin_unlock(&efx->stats_lock); | ||
1369 | } | ||
1370 | |||
1371 | void efx_stats_enable(struct efx_nic *efx) | ||
1372 | { | ||
1373 | spin_lock(&efx->stats_lock); | ||
1374 | --efx->stats_disable_count; | ||
1375 | spin_unlock(&efx->stats_lock); | ||
1376 | } | ||
1377 | |||
1363 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ | 1378 | /* Context: process, dev_base_lock or RTNL held, non-blocking. */ |
1364 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | 1379 | static struct net_device_stats *efx_net_stats(struct net_device *net_dev) |
1365 | { | 1380 | { |
@@ -1368,12 +1383,12 @@ static struct net_device_stats *efx_net_stats(struct net_device *net_dev) | |||
1368 | struct net_device_stats *stats = &net_dev->stats; | 1383 | struct net_device_stats *stats = &net_dev->stats; |
1369 | 1384 | ||
1370 | /* Update stats if possible, but do not wait if another thread | 1385 | /* Update stats if possible, but do not wait if another thread |
1371 | * is updating them (or resetting the NIC); slightly stale | 1386 | * is updating them or if MAC stats fetches are temporarily |
1372 | * stats are acceptable. | 1387 | * disabled; slightly stale stats are acceptable. |
1373 | */ | 1388 | */ |
1374 | if (!spin_trylock(&efx->stats_lock)) | 1389 | if (!spin_trylock(&efx->stats_lock)) |
1375 | return stats; | 1390 | return stats; |
1376 | if (efx->stats_enabled) { | 1391 | if (!efx->stats_disable_count) { |
1377 | efx->mac_op->update_stats(efx); | 1392 | efx->mac_op->update_stats(efx); |
1378 | falcon_update_nic_stats(efx); | 1393 | falcon_update_nic_stats(efx); |
1379 | } | 1394 | } |
@@ -1626,12 +1641,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method, | |||
1626 | { | 1641 | { |
1627 | EFX_ASSERT_RESET_SERIALISED(efx); | 1642 | EFX_ASSERT_RESET_SERIALISED(efx); |
1628 | 1643 | ||
1629 | /* The net_dev->get_stats handler is quite slow, and will fail | 1644 | efx_stats_disable(efx); |
1630 | * if a fetch is pending over reset. Serialise against it. */ | ||
1631 | spin_lock(&efx->stats_lock); | ||
1632 | efx->stats_enabled = false; | ||
1633 | spin_unlock(&efx->stats_lock); | ||
1634 | |||
1635 | efx_stop_all(efx); | 1645 | efx_stop_all(efx); |
1636 | mutex_lock(&efx->mac_lock); | 1646 | mutex_lock(&efx->mac_lock); |
1637 | mutex_lock(&efx->spi_lock); | 1647 | mutex_lock(&efx->spi_lock); |
@@ -1682,7 +1692,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, | |||
1682 | 1692 | ||
1683 | if (ok) { | 1693 | if (ok) { |
1684 | efx_start_all(efx); | 1694 | efx_start_all(efx); |
1685 | efx->stats_enabled = true; | 1695 | efx_stats_enable(efx); |
1686 | } | 1696 | } |
1687 | return rc; | 1697 | return rc; |
1688 | } | 1698 | } |
@@ -1888,6 +1898,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1888 | efx->rx_checksum_enabled = true; | 1898 | efx->rx_checksum_enabled = true; |
1889 | spin_lock_init(&efx->netif_stop_lock); | 1899 | spin_lock_init(&efx->netif_stop_lock); |
1890 | spin_lock_init(&efx->stats_lock); | 1900 | spin_lock_init(&efx->stats_lock); |
1901 | efx->stats_disable_count = 1; | ||
1891 | mutex_init(&efx->mac_lock); | 1902 | mutex_init(&efx->mac_lock); |
1892 | efx->mac_op = &efx_dummy_mac_operations; | 1903 | efx->mac_op = &efx_dummy_mac_operations; |
1893 | efx->phy_op = &efx_dummy_phy_operations; | 1904 | efx->phy_op = &efx_dummy_phy_operations; |