Commit 9806c984 authored by Dick Kennedy's avatar Dick Kennedy Committed by Martin K. Petersen

scsi: lpfc: Fix NVMe rport deregister and registration during ADISC

During driver unload/reload testing, the NVMe initiator would not
re-establish connectivity to NVMe controllers on reload.

The failing NVMe array supports concurrent FCP and NVMe operation via
different nport_id's. The array was repeatedly sending an ADISC every 2
seconds after PLOGI completed and while NVMe subsystems were executing
discovery. The target would continue this state for roughly 45 seconds.

The driver's current behavior on ADISC receipt is to validate a the ADISC
vs the device and issue a RESUME_RPI to restore transmission. The receipt
of the ADISC effectively caused a driver to take actions similar to a
logout and login for the remote port, causing the deregistration of the
nvme rport and a subsequent re-registration.  This caused a constant reset
and re-connect of the NVMe controller while this 45s window occurred. There
was no need for the state changes as ADISC does not change login state.

This patch corrects this behavior by validating if the remoteport is
already logged in (MAPPED) and when true, avoids the call to set the ndlp
state to MAPPED, which triggers the unreg/re-reg. Thus ADISC does not
change the login state of the node.

Link: https://lore.kernel.org/r/20200630215001.70793-5-jsmart2021@gmail.comSigned-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c93764a6
...@@ -797,11 +797,17 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ...@@ -797,11 +797,17 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
ndlp, NULL); ndlp, NULL);
} }
out: out:
/* If we are authenticated, move to the proper state */ /* If we are authenticated, move to the proper state.
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) * It is possible an ADISC arrived and the remote nport
lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); * is already in MAPPED or UNMAPPED state. Catch this
else * condition and don't set the nlp_state again because
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); * it causes an unnecessary transport unregister/register.
*/
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
if (ndlp->nlp_state != NLP_STE_MAPPED_NODE)
lpfc_nlp_set_state(vport, ndlp,
NLP_STE_MAPPED_NODE);
}
return 1; return 1;
} }
......
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