diff options
author | Justin Tee <justin.tee@broadcom.com> | 2023-01-09 15:33:12 -0800 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2023-01-12 00:03:14 -0500 |
commit | c051f1a424a15b73c493090a9f1c0273398b1637 (patch) | |
tree | c23bc55192a62bc8d03fcf6408c8954add3a809e /drivers/scsi/lpfc | |
parent | ecdf4ddf4eb7a9135abdb358e98a8e6c1e8effe6 (diff) | |
download | lwn-c051f1a424a15b73c493090a9f1c0273398b1637.tar.gz lwn-c051f1a424a15b73c493090a9f1c0273398b1637.zip |
scsi: lpfc: Exit PRLI completion handling early if ndlp not in PRLI_ISSUE state
In a large SAN testing configuration, frequent target port toggle tests are
occasionally resulting in missing lun path rediscoveries. An outstanding
PRLI can be inflight when a target RSCN dissappearance occurs, causing the
driver to retry PRLIs using invalid rpi contexts.
Fix by verifying that an ndlp's state was not restarted from PRLI_ISSUE
due to an intermediate RSCN. If not in a valid state, early exit PRLI
completion handling.
The last follow up RSCN indicating target reappearance retriggers
PLOGI/PRLI with a valid rpi context and is expected to succeed in LUN path
rediscovery.
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 919741bbe267..4d3b8f2036d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2373,15 +2373,30 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* PRLI failed */ lpfc_printf_vlog(vport, mode, loglevel, "2754 PRLI failure DID:%06X Status:x%x/x%x, " - "data: x%x\n", + "data: x%x x%x\n", ndlp->nlp_DID, ulp_status, - ulp_word4, ndlp->fc4_prli_sent); + ulp_word4, ndlp->nlp_state, + ndlp->fc4_prli_sent); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (!lpfc_error_lost_link(ulp_status, ulp_word4)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); + /* The following condition catches an inflight transition + * mismatch typically caused by an RSCN. Skip any + * processing to allow recovery. + */ + if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state <= NLP_STE_REG_LOGIN_ISSUE) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, + "2784 PRLI cmpl: state mismatch " + "DID x%06x nstate x%x nflag x%x\n", + ndlp->nlp_DID, ndlp->nlp_state, + ndlp->nlp_flag); + goto out; + } + /* * For P2P topology, retain the node so that PLOGI can be * attempted on it again. @@ -4673,6 +4688,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* the nameserver fails */ maxretry = 0; delay = 100; + } else if (cmd == ELS_CMD_PRLI && + ndlp->nlp_state != NLP_STE_PRLI_ISSUE) { + /* State-command disagreement. The PRLI was + * failed with an invalid rpi meaning there + * some unexpected state change. Don't retry. + */ + maxretry = 0; + retry = 0; + break; } retry = 1; break; |