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

scsi: lpfc: Fix transition nvme-i rport handling to nport only.

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: 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 7a06dcd3
...@@ -148,8 +148,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -148,8 +148,7 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
struct lpfc_nvmet_tgtport *tgtp; struct lpfc_nvmet_tgtport *tgtp;
struct nvme_fc_local_port *localport; struct nvme_fc_local_port *localport;
struct lpfc_nvme_lport *lport; struct lpfc_nodelist *ndlp;
struct lpfc_nvme_rport *rport;
struct nvme_fc_remote_port *nrport; struct nvme_fc_remote_port *nrport;
char *statep; char *statep;
int len = 0; int len = 0;
...@@ -265,7 +264,6 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -265,7 +264,6 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
len = snprintf(buf, PAGE_SIZE, "NVME Initiator Enabled\n"); len = snprintf(buf, PAGE_SIZE, "NVME Initiator Enabled\n");
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
lport = (struct lpfc_nvme_lport *)localport->private;
/* Port state is only one of two values for now. */ /* Port state is only one of two values for now. */
if (localport->port_id) if (localport->port_id)
...@@ -281,9 +279,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, ...@@ -281,9 +279,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
wwn_to_u64(vport->fc_nodename.u.wwn), wwn_to_u64(vport->fc_nodename.u.wwn),
localport->port_id, statep); 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. */ /* local short-hand pointer. */
nrport = rport->remoteport; nrport = ndlp->nrport->remoteport;
/* Port state is only one of two values for now. */ /* Port state is only one of two values for now. */
switch (nrport->port_state) { switch (nrport->port_state) {
......
...@@ -550,8 +550,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) ...@@ -550,8 +550,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
unsigned char *statep; unsigned char *statep;
struct nvme_fc_local_port *localport; struct nvme_fc_local_port *localport;
struct lpfc_nvme_lport *lport;
struct lpfc_nvme_rport *rport;
struct lpfc_nvmet_tgtport *tgtp; struct lpfc_nvmet_tgtport *tgtp;
struct nvme_fc_remote_port *nrport; struct nvme_fc_remote_port *nrport;
...@@ -660,7 +658,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) ...@@ -660,7 +658,6 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
goto out_exit; goto out_exit;
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
lport = (struct lpfc_nvme_lport *)localport->private;
/* Port state is only one of two values for now. */ /* Port state is only one of two values for now. */
if (localport->port_id) if (localport->port_id)
...@@ -673,9 +670,12 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) ...@@ -673,9 +670,12 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
localport->port_id, statep); localport->port_id, statep);
len += snprintf(buf + len, size - len, "\tRport List:\n"); 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. */ /* 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. */ /* Port state is only one of two values for now. */
switch (nrport->port_state) { switch (nrport->port_state) {
......
...@@ -191,7 +191,6 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) ...@@ -191,7 +191,6 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport)
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
"6146 remoteport delete complete %p\n", "6146 remoteport delete complete %p\n",
remoteport); remoteport);
list_del(&rport->list);
ndlp->nrport = NULL; ndlp->nrport = NULL;
lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp);
...@@ -2208,7 +2207,6 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) ...@@ -2208,7 +2207,6 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport)
lport = (struct lpfc_nvme_lport *)localport->private; lport = (struct lpfc_nvme_lport *)localport->private;
vport->localport = localport; vport->localport = localport;
lport->vport = vport; lport->vport = vport;
INIT_LIST_HEAD(&lport->rport_list);
vport->nvmei_support = 1; vport->nvmei_support = 1;
len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max); len = lpfc_new_nvme_buf(vport, phba->sli4_hba.nvme_xri_max);
vport->phba->total_nvme_bufs += len; vport->phba->total_nvme_bufs += len;
...@@ -2233,7 +2231,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) ...@@ -2233,7 +2231,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
#if (IS_ENABLED(CONFIG_NVME_FC)) #if (IS_ENABLED(CONFIG_NVME_FC))
struct nvme_fc_local_port *localport; struct nvme_fc_local_port *localport;
struct lpfc_nvme_lport *lport; struct lpfc_nvme_lport *lport;
struct lpfc_nvme_rport *rport = NULL, *rport_next = NULL;
int ret; int ret;
if (vport->nvmei_support == 0) if (vport->nvmei_support == 0)
...@@ -2246,19 +2243,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) ...@@ -2246,19 +2243,6 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport)
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME,
"6011 Destroying NVME localport %p\n", "6011 Destroying NVME localport %p\n",
localport); 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's rport list is clear. Unregister
* lport and release resources. * lport and release resources.
...@@ -2384,8 +2368,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ...@@ -2384,8 +2368,6 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
if (!rport->ndlp) if (!rport->ndlp)
return -1; return -1;
ndlp->nrport = rport; ndlp->nrport = rport;
INIT_LIST_HEAD(&rport->list);
list_add_tail(&rport->list, &lport->rport_list);
lpfc_printf_vlog(vport, KERN_INFO, lpfc_printf_vlog(vport, KERN_INFO,
LOG_NVME_DISC | LOG_NODE, LOG_NVME_DISC | LOG_NODE,
"6022 Binding new rport to " "6022 Binding new rport to "
......
...@@ -35,13 +35,11 @@ struct lpfc_nvme_qhandle { ...@@ -35,13 +35,11 @@ struct lpfc_nvme_qhandle {
/* Declare nvme-based local and remote port definitions. */ /* Declare nvme-based local and remote port definitions. */
struct lpfc_nvme_lport { struct lpfc_nvme_lport {
struct lpfc_vport *vport; struct lpfc_vport *vport;
struct list_head rport_list;
struct completion lport_unreg_done; struct completion lport_unreg_done;
/* Add sttats counters here */ /* Add sttats counters here */
}; };
struct lpfc_nvme_rport { struct lpfc_nvme_rport {
struct list_head list;
struct lpfc_nvme_lport *lport; struct lpfc_nvme_lport *lport;
struct nvme_fc_remote_port *remoteport; struct nvme_fc_remote_port *remoteport;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
......
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