Commit b3f2e67c authored by James Smart's avatar James Smart Committed by Martin K. Petersen

scsi: lpfc: Fix NPIV discovery and Fabric Node detection

While testing NPIV and link bounces, the vport would not show a fabric node
for the F_Port, would not transition into NPR state during a link fault, or
leave the FDMI node untouched during error injection. Cause for this was
determined to be an inconsistent manner in which F_Port, Nameserver, and
FDMI controller nodes were created and linked. In some cases, the nodes
would never be unregistered from the transport, leaving references
active. In other cases, the fabric nodes may register with the transport
multiple times while still registered.

The following changes were made:

 - Fix the FDISC issue routine, which starts vport (re)creation, to mark
   the F_Port as a fabric node (NLP_FABRIC) and allow the F_Port node to
   fully be created and show up in the node list.

 - When remote ports are cleaned up on vport termination, cleanup the
   nameserver and FDMI controller nodes on the vport so they unregister
   from the transport.

 - On link bounces, don't exclude the NPIV Fabric remote ports from
   transitioning to the NPR state, allowing them to avoid re-registration
   if already registered.

Link: https://lore.kernel.org/r/20201115192646.12977-9-james.smart@broadcom.comCo-developed-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarDick Kennedy <dick.kennedy@broadcom.com>
Signed-off-by: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9d76d467
...@@ -1508,6 +1508,10 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) ...@@ -1508,6 +1508,10 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
ndlp = lpfc_nlp_init(vport, Fabric_DID); ndlp = lpfc_nlp_init(vport, Fabric_DID);
if (!ndlp) if (!ndlp)
return 0; return 0;
/* NPIV is only supported in Fabrics. */
ndlp->nlp_type |= NLP_FABRIC;
/* Put ndlp onto node list */ /* Put ndlp onto node list */
lpfc_enqueue_node(vport, ndlp); lpfc_enqueue_node(vport, ndlp);
} }
......
...@@ -818,12 +818,13 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) ...@@ -818,12 +818,13 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
struct lpfc_nodelist *ndlp, *next_ndlp; struct lpfc_nodelist *ndlp, *next_ndlp;
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
continue; continue;
if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) || if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
((vport->port_type == LPFC_NPIV_PORT) && ((vport->port_type == LPFC_NPIV_PORT) &&
(ndlp->nlp_DID == NameServer_DID))) ((ndlp->nlp_DID == NameServer_DID) ||
(ndlp->nlp_DID == FDMI_DID))))
lpfc_unreg_rpi(vport, ndlp); lpfc_unreg_rpi(vport, ndlp);
/* Leave Fabric nodes alone on link down */ /* Leave Fabric nodes alone on link down */
...@@ -1037,9 +1038,7 @@ lpfc_linkup_port(struct lpfc_vport *vport) ...@@ -1037,9 +1038,7 @@ lpfc_linkup_port(struct lpfc_vport *vport)
vport->fc_ns_retry = 0; vport->fc_ns_retry = 0;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
if (vport->fc_flag & FC_LBIT) lpfc_linkup_cleanup_nodes(vport);
lpfc_linkup_cleanup_nodes(vport);
} }
static int static int
......
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