Commit 9388da30 authored by Justin Tee's avatar Justin Tee Committed by Martin K. Petersen

scsi: lpfc: Make fabric zone discovery more robust when handling unsolicited LOGO

This patch provides better target rport recovery when a target rport is
running in initiator mode to discover the fabric.  Such a target will issue
a LOGO before switching back to strict target mode and changes are made to
recover the login.  Log messages are also updated accordingly.
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230712180522.112722-8-justintee8345@gmail.comSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 04c32001
...@@ -1557,7 +1557,8 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -1557,7 +1557,8 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
ndlp->nlp_fc4_type |= NLP_FC4_FCP; ndlp->nlp_fc4_type |= NLP_FC4_FCP;
if (fc4_data_1 & LPFC_FC4_TYPE_BITMASK) if (fc4_data_1 & LPFC_FC4_TYPE_BITMASK)
ndlp->nlp_fc4_type |= NLP_FC4_NVME; ndlp->nlp_fc4_type |= NLP_FC4_NVME;
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, lpfc_printf_vlog(vport, KERN_INFO,
LOG_DISCOVERY | LOG_NODE,
"3064 Setting ndlp x%px, DID x%06x " "3064 Setting ndlp x%px, DID x%06x "
"with FC4 x%08x, Data: x%08x x%08x " "with FC4 x%08x, Data: x%08x x%08x "
"%d\n", "%d\n",
...@@ -1568,14 +1569,21 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -1568,14 +1569,21 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
if (ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE && if (ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE &&
ndlp->nlp_fc4_type) { ndlp->nlp_fc4_type) {
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
/* This is a fabric topology so if discovery
lpfc_nlp_set_state(vport, ndlp, * started with an unsolicited PLOGI, don't
NLP_STE_PRLI_ISSUE); * send a PRLI. Targets don't issue PLOGI or
lpfc_issue_els_prli(vport, ndlp, 0); * PRLI when acting as a target. Likely this is
* an initiator function.
*/
if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
lpfc_nlp_set_state(vport, ndlp,
NLP_STE_PRLI_ISSUE);
lpfc_issue_els_prli(vport, ndlp, 0);
}
} else if (!ndlp->nlp_fc4_type) { } else if (!ndlp->nlp_fc4_type) {
/* If fc4 type is still unknown, then LOGO */ /* If fc4 type is still unknown, then LOGO */
lpfc_printf_vlog(vport, KERN_INFO, lpfc_printf_vlog(vport, KERN_INFO,
LOG_DISCOVERY, LOG_DISCOVERY | LOG_NODE,
"6443 Sending LOGO ndlp x%px," "6443 Sending LOGO ndlp x%px,"
"DID x%06x with fc4_type: " "DID x%06x with fc4_type: "
"x%08x, state: %d\n", "x%08x, state: %d\n",
......
...@@ -2376,10 +2376,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2376,10 +2376,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* PRLI failed */ /* PRLI failed */
lpfc_printf_vlog(vport, mode, loglevel, lpfc_printf_vlog(vport, mode, loglevel,
"2754 PRLI failure DID:%06X Status:x%x/x%x, " "2754 PRLI failure DID:%06X Status:x%x/x%x, "
"data: x%x x%x\n", "data: x%x x%x x%x\n",
ndlp->nlp_DID, ulp_status, ndlp->nlp_DID, ulp_status,
ulp_word4, ndlp->nlp_state, ulp_word4, ndlp->nlp_state,
ndlp->fc4_prli_sent); ndlp->fc4_prli_sent, ndlp->nlp_flag);
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4)) if (!lpfc_error_lost_link(vport, ulp_status, ulp_word4))
...@@ -2390,14 +2390,16 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -2390,14 +2390,16 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
* mismatch typically caused by an RSCN. Skip any * mismatch typically caused by an RSCN. Skip any
* processing to allow recovery. * processing to allow recovery.
*/ */
if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && if ((ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE &&
ndlp->nlp_state <= NLP_STE_REG_LOGIN_ISSUE) { ndlp->nlp_state <= NLP_STE_REG_LOGIN_ISSUE) ||
(ndlp->nlp_state == NLP_STE_NPR_NODE &&
ndlp->nlp_flag & NLP_DELAY_TMO)) {
lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE,
"2784 PRLI cmpl: state mismatch " "2784 PRLI cmpl: Allow Node recovery "
"DID x%06x nstate x%x nflag x%x\n", "DID x%06x nstate x%x nflag x%x\n",
ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_DID, ndlp->nlp_state,
ndlp->nlp_flag); ndlp->nlp_flag);
goto out; goto out;
} }
/* /*
......
...@@ -879,23 +879,34 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -879,23 +879,34 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
lpfc_retry_pport_discovery(phba); lpfc_retry_pport_discovery(phba);
} }
} else if ((!(ndlp->nlp_type & NLP_FABRIC) && } else {
((ndlp->nlp_type & NLP_FCP_TARGET) || lpfc_printf_vlog(vport, KERN_INFO,
(ndlp->nlp_type & NLP_NVME_TARGET) || LOG_NODE | LOG_ELS | LOG_DISCOVERY,
(vport->fc_flag & FC_PT2PT))) || "3203 LOGO recover nport x%06x state x%x "
(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { "ntype x%x fc_flag x%x\n",
/* Only try to re-login if this is NOT a Fabric Node ndlp->nlp_DID, ndlp->nlp_state,
* AND the remote NPORT is a FCP/NVME Target or we ndlp->nlp_type, vport->fc_flag);
* are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special
* case for LOGO as a response to ADISC behavior. /* Special cases for rports that recover post LOGO. */
*/ if ((!(ndlp->nlp_type == NLP_FABRIC) &&
mod_timer(&ndlp->nlp_delayfunc, (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET) ||
jiffies + msecs_to_jiffies(1000 * 1)); vport->fc_flag & FC_PT2PT)) ||
spin_lock_irq(&ndlp->lock); (ndlp->nlp_state >= NLP_STE_ADISC_ISSUE ||
ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_state <= NLP_STE_PRLI_ISSUE)) {
spin_unlock_irq(&ndlp->lock); mod_timer(&ndlp->nlp_delayfunc,
jiffies + msecs_to_jiffies(1000 * 1));
ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; spin_lock_irq(&ndlp->lock);
ndlp->nlp_flag |= NLP_DELAY_TMO;
spin_unlock_irq(&ndlp->lock);
ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
lpfc_printf_vlog(vport, KERN_INFO,
LOG_NODE | LOG_ELS | LOG_DISCOVERY,
"3204 Start nlpdelay on DID x%06x "
"nflag x%x lastels x%x ref cnt %u",
ndlp->nlp_DID, ndlp->nlp_flag,
ndlp->nlp_last_elscmd,
kref_read(&ndlp->kref));
}
} }
out: out:
/* Unregister from backend, could have been skipped due to ADISC */ /* Unregister from backend, could have been skipped due to ADISC */
...@@ -1854,7 +1865,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, ...@@ -1854,7 +1865,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
LPFC_MBOXQ_t *mb; LPFC_MBOXQ_t *mb;
LPFC_MBOXQ_t *nextmb; LPFC_MBOXQ_t *nextmb;
struct lpfc_nodelist *ns_ndlp;
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
...@@ -1882,13 +1892,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, ...@@ -1882,13 +1892,6 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
} }
spin_unlock_irq(&phba->hbalock); spin_unlock_irq(&phba->hbalock);
/* 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)
lpfc_els_abort(phba, ns_ndlp);
}
lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment