scsi: lpfc: Fix spinlock_irq issues in lpfc_els_flush_cmd()
authorJames Smart <jsmart2021@gmail.com>
Sun, 22 Sep 2019 03:59:00 +0000 (20:59 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 1 Oct 2019 02:07:10 +0000 (22:07 -0400)
While reviewing the CT behavior, issues with spinlock_irq were seen. The
driver should be using spinlock_irqsave/irqrestore in the els flush
routine.

Changed to spinlock_irqsave/irqrestore.

Link: https://lore.kernel.org/r/20190922035906.10977-15-jsmart2021@gmail.com
Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_els.c

index bd8109b2a083bc9ff8aa218ea72c779caf0160cb..da90c7bf22878b626b46e328d59efdc7421c0a05 100644 (file)
@@ -7991,20 +7991,22 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
        struct lpfc_sli_ring *pring;
        struct lpfc_iocbq *tmp_iocb, *piocb;
        IOCB_t *cmd = NULL;
+       unsigned long iflags = 0;
 
        lpfc_fabric_abort_vport(vport);
+
        /*
         * For SLI3, only the hbalock is required.  But SLI4 needs to coordinate
         * with the ring insert operation.  Because lpfc_sli_issue_abort_iotag
         * ultimately grabs the ring_lock, the driver must splice the list into
         * a working list and release the locks before calling the abort.
         */
-       spin_lock_irq(&phba->hbalock);
+       spin_lock_irqsave(&phba->hbalock, iflags);
        pring = lpfc_phba_elsring(phba);
 
        /* Bail out if we've no ELS wq, like in PCI error recovery case. */
        if (unlikely(!pring)) {
-               spin_unlock_irq(&phba->hbalock);
+               spin_unlock_irqrestore(&phba->hbalock, iflags);
                return;
        }
 
@@ -8045,21 +8047,21 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
 
        if (phba->sli_rev == LPFC_SLI_REV4)
                spin_unlock(&pring->ring_lock);
-       spin_unlock_irq(&phba->hbalock);
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
 
        /* Abort each txcmpl iocb on aborted list and remove the dlist links. */
        list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
-               spin_lock_irq(&phba->hbalock);
+               spin_lock_irqsave(&phba->hbalock, iflags);
                list_del_init(&piocb->dlist);
                lpfc_sli_issue_abort_iotag(phba, pring, piocb);
-               spin_unlock_irq(&phba->hbalock);
+               spin_unlock_irqrestore(&phba->hbalock, iflags);
        }
        if (!list_empty(&abort_list))
                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
                                 "3387 abort list for txq not empty\n");
        INIT_LIST_HEAD(&abort_list);
 
-       spin_lock_irq(&phba->hbalock);
+       spin_lock_irqsave(&phba->hbalock, iflags);
        if (phba->sli_rev == LPFC_SLI_REV4)
                spin_lock(&pring->ring_lock);
 
@@ -8099,7 +8101,7 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
 
        if (phba->sli_rev == LPFC_SLI_REV4)
                spin_unlock(&pring->ring_lock);
-       spin_unlock_irq(&phba->hbalock);
+       spin_unlock_irqrestore(&phba->hbalock, iflags);
 
        /* Cancel all the IOCBs from the completions list */
        lpfc_sli_cancel_iocbs(phba, &abort_list,