mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 19:43:40 +02:00
scsi: lpfc: Defer issuing new PLOGI if received RSCN before completing REG_LOGIN
When mapped to a target with multiple virtual ports, a link bounce sometimes results in unsuccessful rediscovery of all of the target's virtual ports. This is because a succession of repeat RSCNs for the virtual target ports leaves ndlps in the REG_LOGIN state with the NLP_REG_LOGIN_SEND flag set. With NLP_REG_LOGIN_SEND set, during the next PLOGI, the driver will UNREG_RPI. When UNREG_RPI is processed, the driver can be in the middle of PRLI_ISSUE or MAPPED state resulting in an illegal state transition by the discovery engine and stalling. Fix by calling the discovery state machine with DEVICE_RECOVERY event during RSCN processing. This will set the NLP_IGNR_REG_CMPL bit and prevent the old REG_LOGIN state from advancing. Then for the new PLOGI issue, add the check for the NLP_IGNR_REG_CMPL bit to delay issuing the new PLOGI until the queued REG_LOGIN and UNREG_LOGIN have been processed. Signed-off-by: Justin Tee <justin.tee@broadcom.com> Link: https://lore.kernel.org/r/20230301231626.9621-6-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
06578ac65e
commit
1d0f9fea5d
|
|
@ -2208,14 +2208,15 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
|
|||
* outstanding UNREG_RPI mbox command completes, unless we
|
||||
* are going offline. This logic does not apply for Fabric DIDs
|
||||
*/
|
||||
if ((ndlp->nlp_flag & NLP_UNREG_INP) &&
|
||||
if ((ndlp->nlp_flag & (NLP_IGNR_REG_CMPL | NLP_UNREG_INP)) &&
|
||||
((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
|
||||
!(vport->fc_flag & FC_OFFLINE_MODE)) {
|
||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||
"4110 Issue PLOGI x%x deferred "
|
||||
"on NPort x%x rpi x%x Data: x%px\n",
|
||||
"on NPort x%x rpi x%x flg x%x Data:"
|
||||
" x%px\n",
|
||||
ndlp->nlp_defer_did, ndlp->nlp_DID,
|
||||
ndlp->nlp_rpi, ndlp);
|
||||
ndlp->nlp_rpi, ndlp->nlp_flag, ndlp);
|
||||
|
||||
/* We can only defer 1st PLOGI */
|
||||
if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING)
|
||||
|
|
|
|||
|
|
@ -5755,8 +5755,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
|
|||
(NLP_FCP_TARGET | NLP_NVME_TARGET)))
|
||||
return NULL;
|
||||
|
||||
ndlp->nlp_prev_state = ndlp->nlp_state;
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
|
||||
lpfc_disc_state_machine(vport, ndlp, NULL,
|
||||
NLP_EVT_DEVICE_RECOVERY);
|
||||
|
||||
spin_lock_irq(&ndlp->lock);
|
||||
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user