scsi: lpfc: Fix deadlock due to nested hbalock call
authorJames Smart <jsmart2021@gmail.com>
Tue, 12 Mar 2019 23:30:12 +0000 (16:30 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 19 Mar 2019 16:57:02 +0000 (12:57 -0400)
If an adapter fails, causing a board reset, the board reset routine
lpfc_hba_down_s4() takes the hbalock out then calls
lpfc_nvmet_ctxbuf_post() who then tries to take out the same lock.  As the
context lists are now protected under the buf_list_locks, there is no need
for the hbalock to be held by the board reset routine.

Fix by no longer taking the hbalock in the board reset routine.

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_init.c

index 6deb4d2..291ad3b 100644 (file)
@@ -1117,19 +1117,19 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba)
 
                }
        }
+       spin_unlock_irq(&phba->hbalock);
 
        if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) {
-               spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
+               spin_lock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock);
                list_splice_init(&phba->sli4_hba.lpfc_abts_nvmet_ctx_list,
                                 &nvmet_aborts);
-               spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
+               spin_unlock_irq(&phba->sli4_hba.abts_nvmet_buf_list_lock);
                list_for_each_entry_safe(ctxp, ctxp_next, &nvmet_aborts, list) {
                        ctxp->flag &= ~(LPFC_NVMET_XBUSY | LPFC_NVMET_ABORT_OP);
                        lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
                }
        }
 
-       spin_unlock_irq(&phba->hbalock);
        lpfc_sli4_free_sp_events(phba);
        return cnt;
 }