diff options
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; |