Commit 91a52b61 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Fix hardlockup in lpfc_abort_handler

In lpfc_abort_handler, the lock acquire order is hbalock (irqsave),
buf_lock (irq) and ring_lock (irq).  The issue is that in two places the
locks are released out of order - the buf_lock and the hbalock - resulting
in the cpu preemption/lock flags getting restored out of order and
deadlocking the cpu.

Fix the unlock order by fully releasing the hbalocks as well.

CC: Zhangguanghui <zhang.guanghui@h3c.com>
Link: https://lore.kernel.org/r/20191018211832.7917-7-jsmart2021@gmail.com


Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 324e1c40
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -4848,20 +4848,21 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
		ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING,
						abtsiocb, 0);
	}
	/* no longer need the lock after this point */
	spin_unlock_irqrestore(&phba->hbalock, flags);

	if (ret_val == IOCB_ERROR) {
		/* Indicate the IO is not being aborted by the driver. */
		iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED;
		lpfc_cmd->waitq = NULL;
		spin_unlock(&lpfc_cmd->buf_lock);
		spin_unlock_irqrestore(&phba->hbalock, flags);
		lpfc_sli_release_iocbq(phba, abtsiocb);
		ret = FAILED;
		goto out;
	}

	/* no longer need the lock after this point */
	spin_unlock(&lpfc_cmd->buf_lock);
	spin_unlock_irqrestore(&phba->hbalock, flags);

	if (phba->cfg_poll & DISABLE_FCP_RING_INT)
		lpfc_sli_handle_fast_ring_event(phba,