mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 17:14:14 +08:00
scsi: lpfc: Fix PLOGI failure with high remoteport count
When connected to a high number of remote ports, the driver is encountering PLOGI errors. The errors are due to adapter detected failures indicating illegal field values. Turns out the driver was prematurely clearing an RPI bitmask before waiting for an UNREG_RPI mailbox completion. This allowed the RPI to be reused before it was actually available. Fix by clearing RPI bitmask only after UNREG_RPI mailbox completion. Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
31f06d2e73
commit
4f1a2fef2a
@ -157,6 +157,7 @@ struct lpfc_node_rrq {
|
||||
/* Defines for nlp_flag (uint32) */
|
||||
#define NLP_IGNR_REG_CMPL 0x00000001 /* Rcvd rscn before we cmpl reg login */
|
||||
#define NLP_REG_LOGIN_SEND 0x00000002 /* sent reglogin to adapter */
|
||||
#define NLP_RELEASE_RPI 0x00000004 /* Release RPI to free pool */
|
||||
#define NLP_SUPPRESS_RSP 0x00000010 /* Remote NPort supports suppress rsp */
|
||||
#define NLP_PLOGI_SND 0x00000020 /* sent PLOGI request for this entry */
|
||||
#define NLP_PRLI_SND 0x00000040 /* sent PRLI request for this entry */
|
||||
|
@ -4805,6 +4805,10 @@ lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
ndlp->nlp_defer_did = NLP_EVT_NOTHING_PENDING;
|
||||
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
||||
} else {
|
||||
if (ndlp->nlp_flag & NLP_RELEASE_RPI) {
|
||||
lpfc_sli4_free_rpi(vport->phba, ndlp->nlp_rpi);
|
||||
ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
|
||||
}
|
||||
ndlp->nlp_flag &= ~NLP_UNREG_INP;
|
||||
}
|
||||
}
|
||||
@ -5104,6 +5108,8 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||
list_del_init(&ndlp->els_retry_evt.evt_listp);
|
||||
list_del_init(&ndlp->dev_loss_evt.evt_listp);
|
||||
lpfc_cleanup_vports_rrqs(vport, ndlp);
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
ndlp->nlp_flag |= NLP_RELEASE_RPI;
|
||||
lpfc_unreg_rpi(vport, ndlp);
|
||||
|
||||
return 0;
|
||||
@ -6201,8 +6207,6 @@ lpfc_nlp_release(struct kref *kref)
|
||||
spin_lock_irqsave(&phba->ndlp_lock, flags);
|
||||
NLP_CLR_NODE_ACT(ndlp);
|
||||
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
|
||||
|
||||
/* free ndlp memory for final ndlp release */
|
||||
if (NLP_CHK_FREE_REQ(ndlp)) {
|
||||
|
@ -2507,6 +2507,11 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
ndlp->nlp_defer_did = NLP_EVT_NOTHING_PENDING;
|
||||
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
||||
} else {
|
||||
if (ndlp->nlp_flag & NLP_RELEASE_RPI) {
|
||||
lpfc_sli4_free_rpi(vport->phba,
|
||||
ndlp->nlp_rpi);
|
||||
ndlp->nlp_flag &= ~NLP_RELEASE_RPI;
|
||||
}
|
||||
ndlp->nlp_flag &= ~NLP_UNREG_INP;
|
||||
}
|
||||
pmb->ctx_ndlp = NULL;
|
||||
@ -2582,6 +2587,13 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
lpfc_issue_els_plogi(
|
||||
vport, ndlp->nlp_DID, 0);
|
||||
} else {
|
||||
if (ndlp->nlp_flag & NLP_RELEASE_RPI) {
|
||||
lpfc_sli4_free_rpi(
|
||||
vport->phba,
|
||||
ndlp->nlp_rpi);
|
||||
ndlp->nlp_flag &=
|
||||
~NLP_RELEASE_RPI;
|
||||
}
|
||||
ndlp->nlp_flag &= ~NLP_UNREG_INP;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user