sfc: hold filter_sem consistently during reset
authorBert Kenward <bkenward@solarflare.com>
Wed, 11 Jul 2018 10:45:10 +0000 (11:45 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 12 Jul 2018 21:52:04 +0000 (14:52 -0700)
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@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/sfc/efx.c

index 570ec72..ce3a177 100644 (file)
@@ -1871,12 +1871,6 @@ static void efx_remove_filters(struct efx_nic *efx)
        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);
-}
 
 /**************************************************************************
  *
@@ -2688,6 +2682,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
        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)
@@ -2745,9 +2740,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
        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);
 
@@ -2764,6 +2758,7 @@ fail:
        efx->port_initialized = false;
 
        mutex_unlock(&efx->rss_lock);
+       up_write(&efx->filter_sem);
        mutex_unlock(&efx->mac_lock);
 
        return rc;
@@ -3473,7 +3468,9 @@ static int efx_pci_probe_main(struct efx_nic *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");
@@ -3765,7 +3762,9 @@ static int efx_pm_resume(struct device *dev)
        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);