[PATCH 4.17 256/324] sfc: hold filter_sem consistently during reset

From: Greg Kroah-Hartman
Date: Thu Aug 23 2018 - 05:03:53 EST


4.17-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bert Kenward <bkenward@xxxxxxxxxxxxxx>

[ Upstream commit 193f20033c54db0dc9563f722fbafbcd5fa0e80d ]

We should take and release the filter_sem consistently during the
reset process, in the same manner as the mac_lock and reset_lock.

For lockdep consistency we also take the filter_sem for write around
other calls to efx->type->init().

Fixes: c2bebe37c6b6 ("sfc: give ef10 its own rwsem in the filter table instead of filter_lock")
Signed-off-by: Bert Kenward <bkenward@xxxxxxxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/sfc/efx.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)

--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -1840,12 +1840,6 @@ static void efx_remove_filters(struct ef
up_write(&efx->filter_sem);
}

-static void efx_restore_filters(struct efx_nic *efx)
-{
- down_read(&efx->filter_sem);
- efx->type->filter_table_restore(efx);
- up_read(&efx->filter_sem);
-}

/**************************************************************************
*
@@ -2657,6 +2651,7 @@ void efx_reset_down(struct efx_nic *efx,
efx_disable_interrupts(efx);

mutex_lock(&efx->mac_lock);
+ down_write(&efx->filter_sem);
mutex_lock(&efx->rss_lock);
if (efx->port_initialized && method != RESET_TYPE_INVISIBLE &&
method != RESET_TYPE_DATAPATH)
@@ -2714,9 +2709,8 @@ int efx_reset_up(struct efx_nic *efx, en
if (efx->type->rx_restore_rss_contexts)
efx->type->rx_restore_rss_contexts(efx);
mutex_unlock(&efx->rss_lock);
- down_read(&efx->filter_sem);
- efx_restore_filters(efx);
- up_read(&efx->filter_sem);
+ efx->type->filter_table_restore(efx);
+ up_write(&efx->filter_sem);
if (efx->type->sriov_reset)
efx->type->sriov_reset(efx);

@@ -2733,6 +2727,7 @@ fail:
efx->port_initialized = false;

mutex_unlock(&efx->rss_lock);
+ up_write(&efx->filter_sem);
mutex_unlock(&efx->mac_lock);

return rc;
@@ -3440,7 +3435,9 @@ static int efx_pci_probe_main(struct efx

efx_init_napi(efx);

+ down_write(&efx->filter_sem);
rc = efx->type->init(efx);
+ up_write(&efx->filter_sem);
if (rc) {
netif_err(efx, probe, efx->net_dev,
"failed to initialise NIC\n");
@@ -3729,7 +3726,9 @@ static int efx_pm_resume(struct device *
rc = efx->type->reset(efx, RESET_TYPE_ALL);
if (rc)
return rc;
+ down_write(&efx->filter_sem);
rc = efx->type->init(efx);
+ up_write(&efx->filter_sem);
if (rc)
return rc;
rc = efx_pm_thaw(dev);