[07/42] lpfc: Fix port relogin failure due to GID_FT interaction
diff mbox series

Message ID 20190814235712.4487-8-jsmart2021@gmail.com
State Accepted
Headers show
  • lpfc: Update lpfc to revision
Related show

Commit Message

James Smart Aug. 14, 2019, 11:56 p.m. UTC
In cases of remote-port-side cable pull/replug, there happens to
be a target that upon replug will send the port a PLOGI, a PRLI,
and a LOGO.  When this sequence is received by the driver, the
PLOGI accepted and a GFT_ID is issued to find the protocol support
for the remote port. While the GFT_ID is outstanding, a LOGO is
received. The driver logs the remote port out and unregisters the
RPI and schedules a new PLOGI transmission. However, the GFT_ID
was not terminated. When it completed, the driver attempted to
transition the remote port to PRLI transmission, which cancels
the PLOGI scheduling. The PRLI transmit attempt is rejected by the
adapter as the remote port is not logged in. No retry is attempted
as it's expected the logout is noted and the supposedly scheduled
PLOGI should address the state. As there is no PLOGI, the remote
port does not get re-discovered.

Fix by aborting the outstanding GFT_ID if the related remote port is
logged out.

Ensure a PRLI transmit attempt only occurs if the remote port is
logging in. This avoids the incorrect attempt while logged out.

Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
 drivers/scsi/lpfc/lpfc_ct.c        | 15 ++++++++++-----
 drivers/scsi/lpfc/lpfc_nportdisc.c |  8 ++++++++
 2 files changed, 18 insertions(+), 5 deletions(-)

diff mbox series

diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index ec72c39997d2..3246942ff2ff 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1210,13 +1210,18 @@  lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 				ndlp->nlp_fc4_type |= NLP_FC4_NVME;
 			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 					 "3064 Setting ndlp %p, DID x%06x with "
-					 "FC4 x%08x, Data: x%08x x%08x\n",
+					 "FC4 x%08x, Data: x%08x x%08x %d\n",
 					 ndlp, did, ndlp->nlp_fc4_type,
-			ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
+					 ndlp->nlp_state);
-			lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
-			lpfc_issue_els_prli(vport, ndlp, 0);
+			if (ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE) {
+				ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
+				lpfc_nlp_set_state(vport, ndlp,
+						   NLP_STE_PRLI_ISSUE);
+				lpfc_issue_els_prli(vport, ndlp, 0);
+			}
 	} else
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 59252bfca14e..c58000cd744f 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1661,6 +1661,7 @@  lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
 	LPFC_MBOXQ_t	  *mb;
 	LPFC_MBOXQ_t	  *nextmb;
 	struct lpfc_dmabuf *mp;
+	struct lpfc_nodelist *ns_ndlp;
 	cmdiocb = (struct lpfc_iocbq *) arg;
@@ -1693,6 +1694,13 @@  lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
+	/* software abort if any GID_FT is outstanding */
+	if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {
+		ns_ndlp = lpfc_findnode_did(vport, NameServer_DID);
+		if (ns_ndlp && NLP_CHK_NODE_ACT(ns_ndlp))
+			lpfc_els_abort(phba, ns_ndlp);
+	}
 	lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
 	return ndlp->nlp_state;