In situations where zoning is not being used, thus NVMe initiators
see other NVMe initiators as well as NVMe targets, a link bounce
on an initiator will cause the NVMe initiators to spew "6169" State
Error messages.

The driver is not qualifying whether the remote port is a NVMe
targer or not before calling the lpfc_nvme_rescan_port(), which
validates the role and prints the message if its only an NVMe
initiator.

Fix by the following:
- before calling lpfc_nvme_rescan_port() ensure that the node is a
  NVMe storage target or a NVMe discovery controller.
- Clean up implementation of lpfc_nvme_rescan_port. remoteport pointer
  will always be NULL if a NVMe initiator only. But, grabbing of
  remoteport pointer should be done under lock to coincide with
  the registering of the remote port with the fc transport.

Signed-off-by: Dick Kennedy <dick.kenn...@broadcom.com>
Signed-off-by: James Smart <jsmart2...@gmail.com>
---
 drivers/scsi/lpfc/lpfc_els.c  | 12 ++++++++++--
 drivers/scsi/lpfc/lpfc_nvme.c | 31 +++++++++++++++++--------------
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 8103635adc38..d919f3161160 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -6360,7 +6360,11 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
                        continue;
                }
 
-               if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
+               /* Check to see if we need to NVME rescan this target
+                * remoteport.
+                */
+               if (ndlp->nlp_fc4_type & NLP_FC4_NVME &&
+                   ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY))
                        lpfc_nvme_rescan_port(vport, ndlp);
 
                lpfc_disc_state_machine(vport, ndlp, NULL,
@@ -6474,7 +6478,11 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct 
lpfc_iocbq *cmdiocb,
                                 *lp, vport->fc_flag, payload_len);
                lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
 
-               if (ndlp->nlp_fc4_type & NLP_FC4_NVME)
+               /* Check to see if we need to NVME rescan this target
+                * remoteport.
+                */
+               if (ndlp->nlp_fc4_type & NLP_FC4_NVME &&
+                   ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY))
                        lpfc_nvme_rescan_port(vport, ndlp);
                return 0;
        }
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 9746808cf94f..e8924e90c4eb 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2426,20 +2426,23 @@ void
 lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
 {
 #if (IS_ENABLED(CONFIG_NVME_FC))
-       struct lpfc_nvme_rport *rport;
-       struct nvme_fc_remote_port *remoteport;
+       struct lpfc_nvme_rport *nrport;
+       struct nvme_fc_remote_port *remoteport = NULL;
 
-       rport = ndlp->nrport;
+       spin_lock_irq(&vport->phba->hbalock);
+       nrport = lpfc_ndlp_get_nrport(ndlp);
+       if (nrport)
+               remoteport = nrport->remoteport;
+       spin_unlock_irq(&vport->phba->hbalock);
 
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
                         "6170 Rescan NPort DID x%06x type x%x "
-                        "state x%x rport %p\n",
-                        ndlp->nlp_DID, ndlp->nlp_type, ndlp->nlp_state, rport);
-       if (!rport)
-               goto input_err;
-       remoteport = rport->remoteport;
-       if (!remoteport)
-               goto input_err;
+                        "state x%x nrport x%px remoteport x%px\n",
+                        ndlp->nlp_DID, ndlp->nlp_type, ndlp->nlp_state,
+                        nrport, remoteport);
+
+       if (!nrport || !remoteport)
+               goto rescan_exit;
 
        /* Only rescan if we are an NVME target in the MAPPED state */
        if (remoteport->port_role & FC_PORT_ROLE_NVME_DISCOVERY &&
@@ -2452,10 +2455,10 @@ lpfc_nvme_rescan_port(struct lpfc_vport *vport, struct 
lpfc_nodelist *ndlp)
                                 ndlp->nlp_DID, remoteport->port_state);
        }
        return;
-input_err:
-       lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
-                        "6169 State error: lport %p, rport%p FCID x%06x\n",
-                        vport->localport, ndlp->rport, ndlp->nlp_DID);
+ rescan_exit:
+       lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
+                        "6169 Skip NVME Rport Rescan, NVME remoteport "
+                        "unregistered\n");
 #endif
 }
 
-- 
2.13.7

Reply via email to