scsi: lpfc: Skip issuing ADISC when node is in NPR state
When a node moves to NPR state due to a device recovery event, the nlp_fc4_types in the node are cleared. An ADISC received for a node in the NPR state triggers an ADISC. Without fc4 types being known, the calls to register with the transport are no-op'd, thus no additional references are placed on the node by transport re-registrations. A subsequent RSCN could trigger another unregister request, which will decrement the reference counts, leading to the ref count hitting zero and the node being freed while futher discovery on the node is being attempted by the RSCN event handling. Fix by skipping the trigger of an ADISC when in NPR state. The normal ADISC process will kick off in the regular discovery path after receiving a response from name server. Link: https://lore.kernel.org/r/20210707184351.67872-19-jsmart2021@gmail.com Co-developed-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: Justin Tee <justin.tee@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
02607fbaf0
commit
ab80386088
|
@ -736,9 +736,13 @@ out:
|
||||||
* is already in MAPPED or UNMAPPED state. Catch this
|
* is already in MAPPED or UNMAPPED state. Catch this
|
||||||
* condition and don't set the nlp_state again because
|
* condition and don't set the nlp_state again because
|
||||||
* it causes an unnecessary transport unregister/register.
|
* it causes an unnecessary transport unregister/register.
|
||||||
|
*
|
||||||
|
* Nodes marked for ADISC will move MAPPED or UNMAPPED state
|
||||||
|
* after issuing ADISC
|
||||||
*/
|
*/
|
||||||
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
|
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
|
||||||
if (ndlp->nlp_state != NLP_STE_MAPPED_NODE)
|
if ((ndlp->nlp_state != NLP_STE_MAPPED_NODE) &&
|
||||||
|
!(ndlp->nlp_flag & NLP_NPR_ADISC))
|
||||||
lpfc_nlp_set_state(vport, ndlp,
|
lpfc_nlp_set_state(vport, ndlp,
|
||||||
NLP_STE_MAPPED_NODE);
|
NLP_STE_MAPPED_NODE);
|
||||||
}
|
}
|
||||||
|
@ -2646,14 +2650,13 @@ lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
|
||||||
|
|
||||||
if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
|
if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
|
||||||
if (ndlp->nlp_flag & NLP_NPR_ADISC) {
|
/*
|
||||||
spin_lock_irq(&ndlp->lock);
|
* ADISC nodes will be handled in regular discovery path after
|
||||||
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
|
* receiving response from NS.
|
||||||
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
*
|
||||||
spin_unlock_irq(&ndlp->lock);
|
* For other nodes, Send PLOGI to trigger an implicit LOGO.
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
|
*/
|
||||||
lpfc_issue_els_adisc(vport, ndlp, 0);
|
if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
|
||||||
} else {
|
|
||||||
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
||||||
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
||||||
|
@ -2686,12 +2689,13 @@ lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
*/
|
*/
|
||||||
if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
|
if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
|
||||||
!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
|
!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
|
||||||
if (ndlp->nlp_flag & NLP_NPR_ADISC) {
|
/*
|
||||||
ndlp->nlp_flag &= ~NLP_NPR_ADISC;
|
* ADISC nodes will be handled in regular discovery path after
|
||||||
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
* receiving response from NS.
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
|
*
|
||||||
lpfc_issue_els_adisc(vport, ndlp, 0);
|
* For other nodes, Send PLOGI to trigger an implicit LOGO.
|
||||||
} else {
|
*/
|
||||||
|
if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
|
||||||
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
|
||||||
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
|
||||||
|
|
Loading…
Reference in New Issue