sfc: Wait for MC reboot to complete before scheduling driver reset
authorDaniel Pieczko <dpieczko@solarflare.com>
Wed, 18 Sep 2013 09:16:24 +0000 (10:16 +0100)
committerBen Hutchings <bhutchings@solarflare.com>
Fri, 20 Sep 2013 16:18:33 +0000 (17:18 +0100)
Scheduling a reset following an MC reboot event before waiting for
reboot to complete results in a race that can lead to a state where
must_realloc_vis is false in efx_ef10_fini_dmaq() but the VIs have
been destroyed during the MC reboot.

To avoid MC errors when trying to remove VIs that do not exist, wait
for the MC reboot to complete before scheduling the reset.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
drivers/net/ethernet/sfc/mcdi.c

index 128d7cdf9eb207583afc36dc8706ef3503b3f5a5..73143ece48329c1f766f89348f418a2b4cad7c4e 100644 (file)
@@ -800,9 +800,6 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
        } else {
                int count;
 
-               /* Nobody was waiting for an MCDI request, so trigger a reset */
-               efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
-
                /* Consume the status word since efx_mcdi_rpc_finish() won't */
                for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) {
                        if (efx_mcdi_poll_reboot(efx))
@@ -810,6 +807,9 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
                        udelay(MCDI_STATUS_DELAY_US);
                }
                mcdi->new_epoch = true;
+
+               /* Nobody was waiting for an MCDI request, so trigger a reset */
+               efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
        }
 
        spin_unlock(&mcdi->iface_lock);