Commit 329f9bc7 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.1.12 : Reference count node structures for node lifetime management

Reference count node structures for node lifetime management.
Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 2680eeaa
...@@ -51,8 +51,9 @@ int lpfc_can_disctmo(struct lpfc_hba *); ...@@ -51,8 +51,9 @@ int lpfc_can_disctmo(struct lpfc_hba *);
int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *); int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *);
int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *, struct lpfc_nodelist *); struct lpfc_iocbq *, struct lpfc_nodelist *);
int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *);
void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t);
struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *);
int lpfc_nlp_put(struct lpfc_nodelist *);
struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t);
void lpfc_disc_list_loopmap(struct lpfc_hba *); void lpfc_disc_list_loopmap(struct lpfc_hba *);
void lpfc_disc_start(struct lpfc_hba *); void lpfc_disc_start(struct lpfc_hba *);
......
...@@ -69,7 +69,6 @@ struct lpfc_nodelist { ...@@ -69,7 +69,6 @@ struct lpfc_nodelist {
uint16_t nlp_maxframe; /* Max RCV frame size */ uint16_t nlp_maxframe; /* Max RCV frame size */
uint8_t nlp_class_sup; /* Supported Classes */ uint8_t nlp_class_sup; /* Supported Classes */
uint8_t nlp_retry; /* used for ELS retries */ uint8_t nlp_retry; /* used for ELS retries */
uint8_t nlp_disc_refcnt; /* used for DSM */
uint8_t nlp_fcp_info; /* class info, bits 0-3 */ uint8_t nlp_fcp_info; /* class info, bits 0-3 */
#define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */
...@@ -80,6 +79,7 @@ struct lpfc_nodelist { ...@@ -80,6 +79,7 @@ struct lpfc_nodelist {
struct lpfc_work_evt els_retry_evt; struct lpfc_work_evt els_retry_evt;
unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_ramp_up_time; /* jiffy of last ramp up */
unsigned long last_q_full_time; /* jiffy of last queue full */ unsigned long last_q_full_time; /* jiffy of last queue full */
struct kref kref;
}; };
/* Defines for nlp_flag (uint32) */ /* Defines for nlp_flag (uint32) */
...@@ -107,7 +107,6 @@ struct lpfc_nodelist { ...@@ -107,7 +107,6 @@ struct lpfc_nodelist {
ACC */ ACC */
#define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from
NPR list */ NPR list */
#define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */
#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
/* Defines for list searchs */ /* Defines for list searchs */
......
This diff is collapsed.
...@@ -158,6 +158,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) ...@@ -158,6 +158,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
else { else {
rdata->pnode = NULL; rdata->pnode = NULL;
ndlp->rport = NULL; ndlp->rport = NULL;
lpfc_nlp_put(ndlp);
put_device(&rport->dev);
} }
return; return;
...@@ -960,6 +962,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -960,6 +962,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free( pmb, phba->mbox_mem_pool);
lpfc_nlp_put(ndlp);
return; return;
} }
...@@ -986,11 +989,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -986,11 +989,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
ndlp = (struct lpfc_nodelist *) pmb->context2; ndlp = (struct lpfc_nodelist *) pmb->context2;
mp = (struct lpfc_dmabuf *) (pmb->context1); mp = (struct lpfc_dmabuf *) (pmb->context1);
pmb->context1 = NULL;
pmb->context2 = NULL;
if (mb->mbxStatus) { if (mb->mbxStatus) {
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp);
/* FLOGI failed, so just use loop map to make discovery list */ /* FLOGI failed, so just use loop map to make discovery list */
lpfc_disc_list_loopmap(phba); lpfc_disc_list_loopmap(phba);
...@@ -1000,12 +1006,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1000,12 +1006,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return; return;
} }
pmb->context1 = NULL;
ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_rpi = mb->un.varWords[0];
ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_type |= NLP_FABRIC;
lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE);
lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { if (phba->hba_state == LPFC_FABRIC_CFG_LINK) {
/* This NPort has been assigned an NPort_ID by the fabric as a /* This NPort has been assigned an NPort_ID by the fabric as a
* result of the completed fabric login. Issue a State Change * result of the completed fabric login. Issue a State Change
...@@ -1027,7 +1033,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1027,7 +1033,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_disc_start(phba); lpfc_disc_start(phba);
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
return; return;
} else { } else {
lpfc_nlp_init(phba, ndlp, NameServer_DID); lpfc_nlp_init(phba, ndlp, NameServer_DID);
...@@ -1050,7 +1056,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1050,7 +1056,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
return; return;
} }
...@@ -1075,6 +1081,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1075,6 +1081,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
mp = (struct lpfc_dmabuf *) (pmb->context1); mp = (struct lpfc_dmabuf *) (pmb->context1);
if (mb->mbxStatus) { if (mb->mbxStatus) {
lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
...@@ -1110,6 +1117,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1110,6 +1117,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
lpfc_disc_start(phba); lpfc_disc_start(phba);
} }
lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free( pmb, phba->mbox_mem_pool);
...@@ -1118,8 +1126,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -1118,8 +1126,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
} }
static void static void
lpfc_register_remote_port(struct lpfc_hba * phba, lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
struct lpfc_nodelist * ndlp)
{ {
struct fc_rport *rport; struct fc_rport *rport;
struct lpfc_rport_data *rdata; struct lpfc_rport_data *rdata;
...@@ -1131,8 +1138,19 @@ lpfc_register_remote_port(struct lpfc_hba * phba, ...@@ -1131,8 +1138,19 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
rport_ids.port_id = ndlp->nlp_DID; rport_ids.port_id = ndlp->nlp_DID;
rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
/*
* We leave our node pointer in rport->dd_data when we unregister a
* FCP target port. But fc_remote_port_add zeros the space to which
* rport->dd_data points. So, if we're reusing a previously
* registered port, drop the reference that we took the last time we
* registered the port.
*/
if (ndlp->rport && ndlp->rport->dd_data &&
*(struct lpfc_rport_data **) ndlp->rport->dd_data) {
lpfc_nlp_put(ndlp);
}
ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
if (!rport) { if (!rport || !get_device(&rport->dev)) {
dev_printk(KERN_WARNING, &phba->pcidev->dev, dev_printk(KERN_WARNING, &phba->pcidev->dev,
"Warning: fc_remote_port_add failed\n"); "Warning: fc_remote_port_add failed\n");
return; return;
...@@ -1142,7 +1160,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, ...@@ -1142,7 +1160,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
rport->maxframe_size = ndlp->nlp_maxframe; rport->maxframe_size = ndlp->nlp_maxframe;
rport->supported_classes = ndlp->nlp_class_sup; rport->supported_classes = ndlp->nlp_class_sup;
rdata = rport->dd_data; rdata = rport->dd_data;
rdata->pnode = ndlp; rdata->pnode = lpfc_nlp_get(ndlp);
if (ndlp->nlp_type & NLP_FCP_TARGET) if (ndlp->nlp_type & NLP_FCP_TARGET)
rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
...@@ -1162,8 +1180,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, ...@@ -1162,8 +1180,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba,
} }
static void static void
lpfc_unregister_remote_port(struct lpfc_hba * phba, lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
struct lpfc_nodelist * ndlp)
{ {
struct fc_rport *rport = ndlp->rport; struct fc_rport *rport = ndlp->rport;
struct lpfc_rport_data *rdata = rport->dd_data; struct lpfc_rport_data *rdata = rport->dd_data;
...@@ -1171,6 +1188,8 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba, ...@@ -1171,6 +1188,8 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba,
if (rport->scsi_target_id == -1) { if (rport->scsi_target_id == -1) {
ndlp->rport = NULL; ndlp->rport = NULL;
rdata->pnode = NULL; rdata->pnode = NULL;
lpfc_nlp_put(ndlp);
put_device(&rport->dev);
} }
fc_remote_port_delete(rport); fc_remote_port_delete(rport);
...@@ -1416,7 +1435,7 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) ...@@ -1416,7 +1435,7 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
lpfc_nlp_counters(phba, ndlp->nlp_state, -1); lpfc_nlp_counters(phba, ndlp->nlp_state, -1);
lpfc_delink_node(phba, ndlp); lpfc_delink_node(phba, ndlp);
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
/* /*
...@@ -1654,6 +1673,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1654,6 +1673,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
} }
list_del(&mb->list); list_del(&mb->list);
mempool_free(mb, phba->mbox_mem_pool); mempool_free(mb, phba->mbox_mem_pool);
lpfc_nlp_put(ndlp);
} }
} }
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
...@@ -1679,8 +1699,8 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1679,8 +1699,8 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
* If we are in the middle of using the nlp in the discovery state * If we are in the middle of using the nlp in the discovery state
* machine, defer the free till we reach the end of the state machine. * machine, defer the free till we reach the end of the state machine.
*/ */
int static void
lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
{ {
struct lpfc_rport_data *rdata; struct lpfc_rport_data *rdata;
...@@ -1688,22 +1708,14 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) ...@@ -1688,22 +1708,14 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp)
lpfc_cancel_retry_delay_tmo(phba, ndlp); lpfc_cancel_retry_delay_tmo(phba, ndlp);
} }
if (ndlp->nlp_disc_refcnt) { lpfc_freenode(phba, ndlp);
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag |= NLP_DELAY_REMOVE;
spin_unlock_irq(phba->host->host_lock);
} else {
lpfc_freenode(phba, ndlp);
if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
rdata = ndlp->rport->dd_data;
rdata->pnode = NULL;
ndlp->rport = NULL;
}
mempool_free( ndlp, phba->nlp_mem_pool); if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) {
put_device(&ndlp->rport->dev);
rdata = ndlp->rport->dd_data;
rdata->pnode = NULL;
ndlp->rport = NULL;
} }
return 0;
} }
static int static int
...@@ -2069,14 +2081,14 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) ...@@ -2069,14 +2081,14 @@ lpfc_disc_flush_list(struct lpfc_hba * phba)
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,
nlp_listp) { nlp_listp) {
lpfc_free_tx(phba, ndlp); lpfc_free_tx(phba, ndlp);
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
} }
if (phba->fc_adisc_cnt) { if (phba->fc_adisc_cnt) {
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
nlp_listp) { nlp_listp) {
lpfc_free_tx(phba, ndlp); lpfc_free_tx(phba, ndlp);
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
} }
return; return;
...@@ -2195,7 +2207,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) ...@@ -2195,7 +2207,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba)
/* Next look for NameServer ndlp */ /* Next look for NameServer ndlp */
ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID);
if (ndlp) if (ndlp)
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
/* Start discovery */ /* Start discovery */
lpfc_disc_start(phba); lpfc_disc_start(phba);
break; break;
...@@ -2373,9 +2385,11 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ...@@ -2373,9 +2385,11 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60);
} }
/* Mailbox took a reference to the node */
lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
mempool_free( pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
return; return;
} }
...@@ -2460,8 +2474,7 @@ lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, ...@@ -2460,8 +2474,7 @@ lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order,
} }
void void
lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did)
uint32_t did)
{ {
memset(ndlp, 0, sizeof (struct lpfc_nodelist)); memset(ndlp, 0, sizeof (struct lpfc_nodelist));
INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
...@@ -2471,5 +2484,29 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ...@@ -2471,5 +2484,29 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
ndlp->nlp_DID = did; ndlp->nlp_DID = did;
ndlp->nlp_phba = phba; ndlp->nlp_phba = phba;
ndlp->nlp_sid = NLP_NO_SID; ndlp->nlp_sid = NLP_NO_SID;
kref_init(&ndlp->kref);
return; return;
} }
void
lpfc_nlp_release(struct kref *kref)
{
struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
kref);
lpfc_nlp_remove(ndlp->nlp_phba, ndlp);
mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool);
}
struct lpfc_nodelist *
lpfc_nlp_get(struct lpfc_nodelist *ndlp)
{
if (ndlp)
kref_get(&ndlp->kref);
return ndlp;
}
int
lpfc_nlp_put(struct lpfc_nodelist *ndlp)
{
return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0;
}
...@@ -1187,12 +1187,12 @@ lpfc_cleanup(struct lpfc_hba * phba) ...@@ -1187,12 +1187,12 @@ lpfc_cleanup(struct lpfc_hba * phba)
lpfc_can_disctmo(phba); lpfc_can_disctmo(phba);
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list,
...@@ -1202,27 +1202,27 @@ lpfc_cleanup(struct lpfc_hba * phba) ...@@ -1202,27 +1202,27 @@ lpfc_cleanup(struct lpfc_hba * phba)
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list,
nlp_listp) { nlp_listp) {
lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp);
} }
INIT_LIST_HEAD(&phba->fc_nlpmap_list); INIT_LIST_HEAD(&phba->fc_nlpmap_list);
...@@ -1510,7 +1510,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) ...@@ -1510,7 +1510,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
INIT_LIST_HEAD(&phba->fc_prli_list); INIT_LIST_HEAD(&phba->fc_prli_list);
INIT_LIST_HEAD(&phba->fc_npr_list); INIT_LIST_HEAD(&phba->fc_npr_list);
pci_set_master(pdev); pci_set_master(pdev);
retval = pci_set_mwi(pdev); retval = pci_set_mwi(pdev);
if (retval) if (retval)
......
...@@ -353,7 +353,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, ...@@ -353,7 +353,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba,
* queue this mbox command to be processed later. * queue this mbox command to be processed later.
*/ */
mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
mbox->context2 = ndlp; /*
* mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox
* command issued in lpfc_cmpl_els_acc().
*/
ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
/* /*
...@@ -773,13 +776,14 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, ...@@ -773,13 +776,14 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba,
default: default:
mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
} }
mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp);
if (lpfc_sli_issue_mbox(phba, mbox, if (lpfc_sli_issue_mbox(phba, mbox,
(MBX_NOWAIT | MBX_STOP_IOCB)) (MBX_NOWAIT | MBX_STOP_IOCB))
!= MBX_NOT_FINISHED) { != MBX_NOT_FINISHED) {
lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
lpfc_nlp_put(ndlp);
mp = (struct lpfc_dmabuf *)mbox->context1; mp = (struct lpfc_dmabuf *)mbox->context1;
lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp); kfree(mp);
...@@ -1920,7 +1924,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, ...@@ -1920,7 +1924,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba,
uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *,
uint32_t); uint32_t);
ndlp->nlp_disc_refcnt++; lpfc_nlp_get(ndlp);
cur_state = ndlp->nlp_state; cur_state = ndlp->nlp_state;
/* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */ /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
...@@ -1943,18 +1947,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, ...@@ -1943,18 +1947,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba,
phba->brd_no, phba->brd_no,
rc, ndlp->nlp_DID, ndlp->nlp_flag); rc, ndlp->nlp_DID, ndlp->nlp_flag);
ndlp->nlp_disc_refcnt--; lpfc_nlp_put(ndlp);
/* Check to see if ndlp removal is deferred */
if ((ndlp->nlp_disc_refcnt == 0)
&& (ndlp->nlp_flag & NLP_DELAY_REMOVE)) {
spin_lock_irq(phba->host->host_lock);
ndlp->nlp_flag &= ~NLP_DELAY_REMOVE;
spin_unlock_irq(phba->host->host_lock);
lpfc_nlp_remove(phba, ndlp);
return NLP_STE_FREED_NODE;
}
if (rc == NLP_STE_FREED_NODE)
return NLP_STE_FREED_NODE;
return rc; return rc;
} }
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