ionic: widen queue_lock use around lif init and deinit
authorShannon Nelson <snelson@pensando.io>
Fri, 1 Oct 2021 18:05:54 +0000 (11:05 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Oct 2021 13:00:21 +0000 (14:00 +0100)
Widen the coverage of the queue_lock to be sure the lif init
and lif deinit actions are protected.  This addresses a hang
seen when a Tx Timeout action was attempted at the same time
as a FW Reset was started.

Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/pensando/ionic/ionic_lif.c

index 4f28cd3..5efa9f1 100644 (file)
@@ -2974,11 +2974,10 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
 
        netif_device_detach(lif->netdev);
 
+       mutex_lock(&lif->queue_lock);
        if (test_bit(IONIC_LIF_F_UP, lif->state)) {
                dev_info(ionic->dev, "Surprise FW stop, stopping queues\n");
-               mutex_lock(&lif->queue_lock);
                ionic_stop_queues(lif);
-               mutex_unlock(&lif->queue_lock);
        }
 
        if (netif_running(lif->netdev)) {
@@ -2989,6 +2988,8 @@ static void ionic_lif_handle_fw_down(struct ionic_lif *lif)
        ionic_reset(ionic);
        ionic_qcqs_free(lif);
 
+       mutex_unlock(&lif->queue_lock);
+
        dev_info(ionic->dev, "FW Down: LIFs stopped\n");
 }
 
@@ -3012,9 +3013,12 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
        err = ionic_port_init(ionic);
        if (err)
                goto err_out;
+
+       mutex_lock(&lif->queue_lock);
+
        err = ionic_qcqs_alloc(lif);
        if (err)
-               goto err_out;
+               goto err_unlock;
 
        err = ionic_lif_init(lif);
        if (err)
@@ -3035,6 +3039,8 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
                        goto err_txrx_free;
        }
 
+       mutex_unlock(&lif->queue_lock);
+
        clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
        ionic_link_status_check_request(lif, CAN_SLEEP);
        netif_device_attach(lif->netdev);
@@ -3051,6 +3057,8 @@ err_lifs_deinit:
        ionic_lif_deinit(lif);
 err_qcqs_free:
        ionic_qcqs_free(lif);
+err_unlock:
+       mutex_unlock(&lif->queue_lock);
 err_out:
        dev_err(ionic->dev, "FW Up: LIFs restart failed - err %d\n", err);
 }