Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68c9b55d authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Fix abort error path for NVMET



rmmod of driver hangs

As driver instances were being unloaded, the NVME target port was unloaded
first. During the unload, the NVME initiator port sent a heartbeat
IO. Because of the target port state, that IO was scheduled for an Abort;
however, that abort subsequently failed. The failure was not cleaned up
properly and lpfc_sli4_xri_exchange_busy_wait silently hung forever.

Clean failed abort properly and make lpfc_sli4_xri_exchange_busy_wait not
hangs silently while waiting for aborts to complete.

Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent d580c613
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -10387,6 +10387,11 @@ lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
	while (!fcp_xri_cmpl || !els_xri_cmpl || !nvme_xri_cmpl ||
	while (!fcp_xri_cmpl || !els_xri_cmpl || !nvme_xri_cmpl ||
	       !nvmet_xri_cmpl) {
	       !nvmet_xri_cmpl) {
		if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
		if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
			if (!nvmet_xri_cmpl)
				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
						"6424 NVMET XRI exchange busy "
						"wait time: %d seconds.\n",
						wait_time/1000);
			if (!nvme_xri_cmpl)
			if (!nvme_xri_cmpl)
				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
						"6100 NVME XRI exchange busy "
						"6100 NVME XRI exchange busy "
+11 −4
Original line number Original line Diff line number Diff line
@@ -1732,9 +1732,12 @@ lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
	uint32_t *payload;
	uint32_t *payload;
	uint32_t size, oxid, sid, rc;
	uint32_t size, oxid, sid, rc;


	fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt);
	oxid = be16_to_cpu(fc_hdr->fh_ox_id);

	if (!nvmebuf || !phba->targetport) {
	if (!nvmebuf || !phba->targetport) {
		lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
		lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
				"6154 LS Drop IO\n");
				"6154 LS Drop IO x%x\n", oxid);
		oxid = 0;
		oxid = 0;
		size = 0;
		size = 0;
		sid = 0;
		sid = 0;
@@ -1744,9 +1747,7 @@ lpfc_nvmet_unsol_ls_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,


	tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
	tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
	payload = (uint32_t *)(nvmebuf->dbuf.virt);
	payload = (uint32_t *)(nvmebuf->dbuf.virt);
	fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt);
	size = bf_get(lpfc_rcqe_length,  &nvmebuf->cq_event.cqe.rcqe_cmpl);
	size = bf_get(lpfc_rcqe_length,  &nvmebuf->cq_event.cqe.rcqe_cmpl);
	oxid = be16_to_cpu(fc_hdr->fh_ox_id);
	sid = sli4_sid_from_fc_hdr(fc_hdr);
	sid = sli4_sid_from_fc_hdr(fc_hdr);


	ctxp = kzalloc(sizeof(struct lpfc_nvmet_rcv_ctx), GFP_ATOMIC);
	ctxp = kzalloc(sizeof(struct lpfc_nvmet_rcv_ctx), GFP_ATOMIC);
@@ -3105,11 +3106,17 @@ lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *phba,
	}
	}


aerr:
aerr:
	ctxp->flag &= ~LPFC_NVMET_ABORT_OP;
	spin_lock_irqsave(&ctxp->ctxlock, flags);
	if (ctxp->flag & LPFC_NVMET_CTX_RLS)
		list_del(&ctxp->list);
	ctxp->flag &= ~(LPFC_NVMET_ABORT_OP | LPFC_NVMET_CTX_RLS);
	spin_unlock_irqrestore(&ctxp->ctxlock, flags);

	atomic_inc(&tgtp->xmt_abort_rsp_error);
	atomic_inc(&tgtp->xmt_abort_rsp_error);
	lpfc_printf_log(phba, KERN_ERR, LOG_NVME_ABTS,
	lpfc_printf_log(phba, KERN_ERR, LOG_NVME_ABTS,
			"6135 Failed to Issue ABTS for oxid x%x. Status x%x\n",
			"6135 Failed to Issue ABTS for oxid x%x. Status x%x\n",
			ctxp->oxid, rc);
			ctxp->oxid, rc);
	lpfc_nvmet_ctxbuf_post(phba, ctxp->ctxbuf);
	return 1;
	return 1;
}
}