From: Justin Tee justin.tee@broadcom.com
[ Upstream commit 98f8d3588097e321be70f83b844fa67d4828fe5c ]
The lpfc_cmpl_ct_disc_fdmi() routine has incorrect logic that treats an FDMI completion with error LOCAL_REJECT/SLI_ABORTED as a success status. Under the erroneous assumption of successful completion, the routine proceeds to issue follow up FDMI commands, which may never complete if the HBA is in an errata state as indicated by the errored completion status. Fix by freeing FDMI cmd resources and early return when the LPFC_SLI_ACTIVE flag is not set and a LOCAL_REJECT/SLI_ABORTED or SLI_DOWN status is received.
Signed-off-by: Justin Tee justin.tee@broadcom.com Link: https://lore.kernel.org/r/20241031223219.152342-6-justintee8345@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_ct.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 134bc96dd1340..ce3a1f42713dd 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -2226,6 +2226,11 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ulp_status, ulp_word4, latt);
if (latt || ulp_status) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY, + "0229 FDMI cmd %04x failed, latt = %d " + "ulp_status: (x%x/x%x), sli_flag x%x\n", + be16_to_cpu(fdmi_cmd), latt, ulp_status, + ulp_word4, phba->sli.sli_flag);
/* Look for a retryable error */ if (ulp_status == IOSTAT_LOCAL_REJECT) { @@ -2234,8 +2239,16 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, case IOERR_SLI_DOWN: /* Driver aborted this IO. No retry as error * is likely Offline->Online or some adapter - * error. Recovery will try again. + * error. Recovery will try again, but if port + * is not active there's no point to continue + * issuing follow up FDMI commands. */ + if (!(phba->sli.sli_flag & LPFC_SLI_ACTIVE)) { + free_ndlp = cmdiocb->ndlp; + lpfc_ct_free_iocb(phba, cmdiocb); + lpfc_nlp_put(free_ndlp); + return; + } break; case IOERR_ABORT_IN_PROGRESS: case IOERR_SEQUENCE_TIMEOUT: @@ -2256,12 +2269,6 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, break; } } - - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0229 FDMI cmd %04x latt = %d " - "ulp_status: x%x, rid x%x\n", - be16_to_cpu(fdmi_cmd), latt, ulp_status, - ulp_word4); }
free_ndlp = cmdiocb->ndlp;