As the devloss API was implemented in the
nvmei driver, an evaluation of the nvme transport
and the lpfc driver showed dual management of the
rports.  This creates a bug possibility when the
thread count and SAN size increases.

The nvmei driver code was based on a very
early transport and was not revisited until the
devloss API was introduced.

Remove the listhead in the driver's rport
data structure and the listhead in the driver's
lport data structure.  Remove all rport_list
traversal.  Convert the driver to use the
nrport (nvme rport) pointer that is now NULL
or nonNULL depending on a devloss action.  Convert
debugfs and nvme_info in sysfs to use the fc_nodes
list in the vport.

Signed-off-by: Dick Kennedy <dick.kenn...@broadcom.com>
Signed-off-by: James Smart <james.sm...@broadcom.com>
---
 drivers/scsi/lpfc/lpfc_attr.c    | 11 ++++++-----
 drivers/scsi/lpfc/lpfc_debugfs.c | 10 +++++-----
 drivers/scsi/lpfc/lpfc_nvme.c    | 18 ------------------
 drivers/scsi/lpfc/lpfc_nvme.h    |  2 --
 4 files changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 37f258fcf6d4..6d9b83cd82a2 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -148,8 +148,7 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
        struct lpfc_hba   *phba = vport->phba;
        struct lpfc_nvmet_tgtport *tgtp;
        struct nvme_fc_local_port *localport;
-       struct lpfc_nvme_lport *lport;
-       struct lpfc_nvme_rport *rport;
+       struct lpfc_nodelist *ndlp;
        struct nvme_fc_remote_port *nrport;
        char *statep;
        int len = 0;
@@ -265,7 +264,6 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
        len = snprintf(buf, PAGE_SIZE, "NVME Initiator Enabled\n");
 
        spin_lock_irq(shost->host_lock);
-       lport = (struct lpfc_nvme_lport *)localport->private;
 
        /* Port state is only one of two values for now. */
        if (localport->port_id)
@@ -281,9 +279,12 @@ lpfc_nvme_info_show(struct device *dev, struct 
device_attribute *attr,
                        wwn_to_u64(vport->fc_nodename.u.wwn),
                        localport->port_id, statep);
 
-       list_for_each_entry(rport, &lport->rport_list, list) {
+       list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+               if (!ndlp->nrport)
+                       continue;
+
                /* local short-hand pointer. */
-               nrport = rport->remoteport;
+               nrport = ndlp->nrport->remoteport;
 
                /* Port state is only one of two values for now. */
                switch (nrport->port_state) {
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 4bcb92c844ca..d71bda24b08e 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -550,8 +550,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char 
*buf, int size)
        struct lpfc_nodelist *ndlp;
        unsigned char *statep;
        struct nvme_fc_local_port *localport;
-       struct lpfc_nvme_lport *lport;
-       struct lpfc_nvme_rport *rport;
        struct lpfc_nvmet_tgtport *tgtp;
        struct nvme_fc_remote_port *nrport;
 
@@ -660,7 +658,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char 
*buf, int size)
                goto out_exit;
 
        spin_lock_irq(shost->host_lock);
-       lport = (struct lpfc_nvme_lport *)localport->private;
 
        /* Port state is only one of two values for now. */
        if (localport->port_id)
@@ -673,9 +670,12 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char 
*buf, int size)
                        localport->port_id, statep);
 
        len += snprintf(buf + len, size - len, "\tRport List:\n");
-       list_for_each_entry(rport, &lport->rport_list, list) {
+       list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
                /* local short-hand pointer. */
-               nrport = rport->remoteport;
+               if (!ndlp->nrport)
+                       continue;
+
+               nrport = ndlp->nrport->remoteport;
 
                /* Port state is only one of two values for now. */
                switch (nrport->port_state) {
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 70675fd7d884..ede42411e57b 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -191,7 +191,6 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port 
*remoteport)
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
                        "6146 remoteport delete complete %p\n",
                        remoteport);
-       list_del(&rport->list);
        ndlp->nrport = NULL;
        lpfc_nlp_put(ndlp);
 
@@ -2208,7 +2207,6 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
                lport = (struct lpfc_nvme_lport *)localport->private;
                vport->localport = localport;
                lport->vport = vport;
-               INIT_LIST_HEAD(&lport->rport_list);
                vport->nvmei_support = 1;
                len  = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max);
                vport->phba->total_nvme_bufs += len;
@@ -2233,7 +2231,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
 #if (IS_ENABLED(CONFIG_NVME_FC))
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
-       struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL;
        int ret;
 
        if (vport->nvmei_support == 0)
@@ -2246,19 +2243,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME,
                         "6011 Destroying NVME localport %p\n",
                         localport);
-       list_for_each_entry_safe(rport, rport_next, &lport->rport_list, list) {
-               /* The last node ref has to get released now before the rport
-                * private memory area is released by the transport.
-                */
-               list_del(&rport->list);
-
-               init_completion(&rport->rport_unreg_done);
-               ret = nvme_fc_unregister_remoteport(rport->remoteport);
-               if (ret)
-                       lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC,
-                                        "6008 rport fail destroy %x\n", ret);
-               wait_for_completion_timeout(&rport->rport_unreg_done, 5);
-       }
 
        /* lport's rport list is clear.  Unregister
         * lport and release resources.
@@ -2384,8 +2368,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct 
lpfc_nodelist *ndlp)
                        if (!rport->ndlp)
                                return -1;
                        ndlp->nrport = rport;
-                       INIT_LIST_HEAD(&rport->list);
-                       list_add_tail(&rport->list, &lport->rport_list);
                        lpfc_printf_vlog(vport, KERN_INFO,
                                         LOG_NVME_DISC | LOG_NODE,
                                         "6022 Binding new rport to "
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
index ec32f45daa66..d192bb268f99 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.h
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
@@ -35,13 +35,11 @@ struct lpfc_nvme_qhandle {
 /* Declare nvme-based local and remote port definitions. */
 struct lpfc_nvme_lport {
        struct lpfc_vport *vport;
-       struct list_head rport_list;
        struct completion lport_unreg_done;
        /* Add sttats counters here */
 };
 
 struct lpfc_nvme_rport {
-       struct list_head list;
        struct lpfc_nvme_lport *lport;
        struct nvme_fc_remote_port *remoteport;
        struct lpfc_nodelist *ndlp;
-- 
2.11.0

Reply via email to