[SCSI] lpfc 8.2.4 : Rework misplaced reference taking on node structure
Rework misplaced reference taking on node structure Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
c95d6c6c2b
commit
fa4066b672
|
@ -561,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
if (vport->load_flag & FC_UNLOADING)
|
if (vport->load_flag & FC_UNLOADING)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
||||||
if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
|
if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
|
||||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
|
||||||
"0216 Link event during NS query\n");
|
"0216 Link event during NS query\n");
|
||||||
|
|
|
@ -120,12 +120,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
|
pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
|
||||||
if (pcmd)
|
if (pcmd)
|
||||||
pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
|
pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
|
||||||
if (!pcmd || !pcmd->virt) {
|
if (!pcmd || !pcmd->virt)
|
||||||
kfree(pcmd);
|
goto els_iocb_free_pcmb_exit;
|
||||||
|
|
||||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pcmd->list);
|
INIT_LIST_HEAD(&pcmd->list);
|
||||||
|
|
||||||
|
@ -135,13 +131,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
if (prsp)
|
if (prsp)
|
||||||
prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
||||||
&prsp->phys);
|
&prsp->phys);
|
||||||
if (!prsp || !prsp->virt) {
|
if (!prsp || !prsp->virt)
|
||||||
kfree(prsp);
|
goto els_iocb_free_prsp_exit;
|
||||||
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
|
|
||||||
kfree(pcmd);
|
|
||||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
INIT_LIST_HEAD(&prsp->list);
|
INIT_LIST_HEAD(&prsp->list);
|
||||||
} else {
|
} else {
|
||||||
prsp = NULL;
|
prsp = NULL;
|
||||||
|
@ -152,15 +143,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
if (pbuflist)
|
if (pbuflist)
|
||||||
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
|
||||||
&pbuflist->phys);
|
&pbuflist->phys);
|
||||||
if (!pbuflist || !pbuflist->virt) {
|
if (!pbuflist || !pbuflist->virt)
|
||||||
lpfc_sli_release_iocbq(phba, elsiocb);
|
goto els_iocb_free_pbuf_exit;
|
||||||
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
|
|
||||||
lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
|
|
||||||
kfree(pcmd);
|
|
||||||
kfree(prsp);
|
|
||||||
kfree(pbuflist);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pbuflist->list);
|
INIT_LIST_HEAD(&pbuflist->list);
|
||||||
|
|
||||||
|
@ -205,7 +189,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
bpl->tus.w = le32_to_cpu(bpl->tus.w);
|
bpl->tus.w = le32_to_cpu(bpl->tus.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* prevent preparing iocb with NULL ndlp reference */
|
||||||
elsiocb->context1 = lpfc_nlp_get(ndlp);
|
elsiocb->context1 = lpfc_nlp_get(ndlp);
|
||||||
|
if (!elsiocb->context1)
|
||||||
|
goto els_iocb_free_pbuf_exit;
|
||||||
elsiocb->context2 = pcmd;
|
elsiocb->context2 = pcmd;
|
||||||
elsiocb->context3 = pbuflist;
|
elsiocb->context3 = pbuflist;
|
||||||
elsiocb->retry = retry;
|
elsiocb->retry = retry;
|
||||||
|
@ -231,8 +218,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
|
||||||
cmdSize);
|
cmdSize);
|
||||||
}
|
}
|
||||||
return elsiocb;
|
return elsiocb;
|
||||||
}
|
|
||||||
|
|
||||||
|
els_iocb_free_pbuf_exit:
|
||||||
|
lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
|
||||||
|
kfree(pbuflist);
|
||||||
|
|
||||||
|
els_iocb_free_prsp_exit:
|
||||||
|
lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
|
||||||
|
kfree(prsp);
|
||||||
|
|
||||||
|
els_iocb_free_pcmb_exit:
|
||||||
|
kfree(pcmd);
|
||||||
|
lpfc_sli_release_iocbq(phba, elsiocb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
|
lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
|
||||||
|
@ -513,6 +512,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
|
|
||||||
/* Check to see if link went down during discovery */
|
/* Check to see if link went down during discovery */
|
||||||
if (lpfc_els_chk_latt(vport)) {
|
if (lpfc_els_chk_latt(vport)) {
|
||||||
|
/* One additional decrement on node reference count to
|
||||||
|
* trigger the release of the node
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -731,6 +733,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
|
if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
|
||||||
|
/* This decrement of reference count to node shall kick off
|
||||||
|
* the release of the node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -754,7 +759,11 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
|
||||||
lpfc_dequeue_node(vport, ndlp);
|
lpfc_dequeue_node(vport, ndlp);
|
||||||
}
|
}
|
||||||
if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
|
if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
|
||||||
|
/* decrement node reference count to trigger the release of
|
||||||
|
* the node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1557,6 +1566,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||||
ndlp->nlp_DID, ELS_CMD_SCR);
|
ndlp->nlp_DID, ELS_CMD_SCR);
|
||||||
|
|
||||||
if (!elsiocb) {
|
if (!elsiocb) {
|
||||||
|
/* This will trigger the release of the node just
|
||||||
|
* allocated
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1578,10 +1590,17 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||||
phba->fc_stat.elsXmitSCR++;
|
phba->fc_stat.elsXmitSCR++;
|
||||||
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
|
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
|
||||||
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
|
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
|
||||||
|
/* The additional lpfc_nlp_put will cause the following
|
||||||
|
* lpfc_els_free_iocb routine to trigger the rlease of
|
||||||
|
* the node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
lpfc_els_free_iocb(phba, elsiocb);
|
lpfc_els_free_iocb(phba, elsiocb);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* This will cause the callback-function lpfc_cmpl_els_cmd to
|
||||||
|
* trigger the release of node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1613,6 +1632,9 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||||
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
||||||
ndlp->nlp_DID, ELS_CMD_RNID);
|
ndlp->nlp_DID, ELS_CMD_RNID);
|
||||||
if (!elsiocb) {
|
if (!elsiocb) {
|
||||||
|
/* This will trigger the release of the node just
|
||||||
|
* allocated
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1649,10 +1671,17 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
|
||||||
phba->fc_stat.elsXmitFARPR++;
|
phba->fc_stat.elsXmitFARPR++;
|
||||||
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
|
elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
|
||||||
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
|
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
|
||||||
|
/* The additional lpfc_nlp_put will cause the following
|
||||||
|
* lpfc_els_free_iocb routine to trigger the release of
|
||||||
|
* the node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
lpfc_els_free_iocb(phba, elsiocb);
|
lpfc_els_free_iocb(phba, elsiocb);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* This will cause the callback-function lpfc_cmpl_els_cmd to
|
||||||
|
* trigger the release of the node.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1712,7 +1741,10 @@ lpfc_els_retry_delay(unsigned long ptr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
evtp->evt_arg1 = ndlp;
|
/* We need to hold the node by incrementing the reference
|
||||||
|
* count until the queued work is done
|
||||||
|
*/
|
||||||
|
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
|
||||||
evtp->evt = LPFC_EVT_ELS_RETRY;
|
evtp->evt = LPFC_EVT_ELS_RETRY;
|
||||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||||
if (phba->work_wait)
|
if (phba->work_wait)
|
||||||
|
@ -2190,6 +2222,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
* thread, just unregister the RPI.
|
* thread, just unregister the RPI.
|
||||||
*/
|
*/
|
||||||
lpfc_unreg_rpi(vport, ndlp);
|
lpfc_unreg_rpi(vport, ndlp);
|
||||||
|
} else {
|
||||||
|
/* Indicate the node has already released, should
|
||||||
|
* not reference to it from within lpfc_els_free_iocb.
|
||||||
|
*/
|
||||||
|
cmdiocb->context1 = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lpfc_els_free_iocb(phba, cmdiocb);
|
lpfc_els_free_iocb(phba, cmdiocb);
|
||||||
|
@ -2208,7 +2245,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
mempool_free(pmb, phba->mbox_mem_pool);
|
mempool_free(pmb, phba->mbox_mem_pool);
|
||||||
if (ndlp) {
|
if (ndlp) {
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
|
|
||||||
/* This is the end of the default RPI cleanup logic for this
|
/* This is the end of the default RPI cleanup logic for this
|
||||||
* ndlp. If no other discovery threads are using this ndlp.
|
* ndlp. If no other discovery threads are using this ndlp.
|
||||||
* we should free all resources associated with it.
|
* we should free all resources associated with it.
|
||||||
|
@ -2236,11 +2272,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
if (cmdiocb->context_un.mbox)
|
if (cmdiocb->context_un.mbox)
|
||||||
mbox = cmdiocb->context_un.mbox;
|
mbox = cmdiocb->context_un.mbox;
|
||||||
|
|
||||||
/* First determine if this is a LS_RJT cmpl */
|
/* First determine if this is a LS_RJT cmpl. Note, this callback
|
||||||
|
* function can have cmdiocb->contest1 (ndlp) field set to NULL.
|
||||||
|
*/
|
||||||
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
|
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
|
||||||
if (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT) {
|
if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
|
||||||
/* A LS_RJT associated with Default RPI cleanup
|
/* A LS_RJT associated with Default RPI cleanup has its own
|
||||||
* has its own seperate code path.
|
* seperate code path.
|
||||||
*/
|
*/
|
||||||
if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
||||||
ls_rjt = 1;
|
ls_rjt = 1;
|
||||||
|
@ -2257,8 +2295,14 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
}
|
}
|
||||||
if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
|
||||||
if (lpfc_nlp_not_used(ndlp))
|
if (lpfc_nlp_not_used(ndlp)) {
|
||||||
ndlp = NULL;
|
ndlp = NULL;
|
||||||
|
/* Indicate the node has already released,
|
||||||
|
* should not reference to it from within
|
||||||
|
* the routine lpfc_els_free_iocb.
|
||||||
|
*/
|
||||||
|
cmdiocb->context1 = NULL;
|
||||||
|
}
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2302,14 +2346,27 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
|
ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
|
||||||
ndlp->nlp_rpi);
|
ndlp->nlp_rpi);
|
||||||
|
|
||||||
if (lpfc_nlp_not_used(ndlp))
|
if (lpfc_nlp_not_used(ndlp)) {
|
||||||
ndlp = NULL;
|
ndlp = NULL;
|
||||||
|
/* Indicate node has already been released,
|
||||||
|
* should not reference to it from within
|
||||||
|
* the routine lpfc_els_free_iocb.
|
||||||
|
*/
|
||||||
|
cmdiocb->context1 = NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Do not drop node for lpfc_els_abort'ed ELS cmds */
|
/* Do not drop node for lpfc_els_abort'ed ELS cmds */
|
||||||
if (!lpfc_error_lost_link(irsp) &&
|
if (!lpfc_error_lost_link(irsp) &&
|
||||||
ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
|
ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
|
||||||
if (lpfc_nlp_not_used(ndlp))
|
if (lpfc_nlp_not_used(ndlp)) {
|
||||||
ndlp = NULL;
|
ndlp = NULL;
|
||||||
|
/* Indicate node has already been
|
||||||
|
* released, should not reference
|
||||||
|
* to it from within the routine
|
||||||
|
* lpfc_els_free_iocb.
|
||||||
|
*/
|
||||||
|
cmdiocb->context1 = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mp = (struct lpfc_dmabuf *) mbox->context1;
|
mp = (struct lpfc_dmabuf *) mbox->context1;
|
||||||
|
@ -2331,7 +2388,12 @@ out:
|
||||||
* resources.
|
* resources.
|
||||||
*/
|
*/
|
||||||
if (ls_rjt)
|
if (ls_rjt)
|
||||||
lpfc_nlp_not_used(ndlp);
|
if (lpfc_nlp_not_used(ndlp))
|
||||||
|
/* Indicate node has already been released,
|
||||||
|
* should not reference to it from within
|
||||||
|
* the routine lpfc_els_free_iocb.
|
||||||
|
*/
|
||||||
|
cmdiocb->context1 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpfc_els_free_iocb(phba, cmdiocb);
|
lpfc_els_free_iocb(phba, cmdiocb);
|
||||||
|
@ -3292,7 +3354,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
|
elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
|
||||||
lpfc_max_els_tries, ndlp,
|
lpfc_max_els_tries, ndlp,
|
||||||
ndlp->nlp_DID, ELS_CMD_ACC);
|
ndlp->nlp_DID, ELS_CMD_ACC);
|
||||||
|
|
||||||
|
/* Decrement the ndlp reference count from previous mbox command */
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
|
|
||||||
if (!elsiocb)
|
if (!elsiocb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3375,11 +3440,13 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
mbox->context2 = lpfc_nlp_get(ndlp);
|
mbox->context2 = lpfc_nlp_get(ndlp);
|
||||||
mbox->vport = vport;
|
mbox->vport = vport;
|
||||||
mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
|
mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
|
||||||
if (lpfc_sli_issue_mbox (phba, mbox, MBX_NOWAIT)
|
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
|
||||||
!= MBX_NOT_FINISHED)
|
!= MBX_NOT_FINISHED)
|
||||||
/* Mbox completion will send ELS Response */
|
/* Mbox completion will send ELS Response */
|
||||||
return 0;
|
return 0;
|
||||||
|
/* Decrement reference count used for the failed mbox
|
||||||
|
* command.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
}
|
}
|
||||||
|
@ -4284,7 +4351,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
lpfc_nlp_put(ndlp);
|
|
||||||
|
|
||||||
if (mb->mbxStatus) {
|
if (mb->mbxStatus) {
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
||||||
|
@ -4317,6 +4383,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
else
|
else
|
||||||
lpfc_do_scr_ns_plogi(phba, vport);
|
lpfc_do_scr_ns_plogi(phba, vport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now, we decrement the ndlp reference count held for this
|
||||||
|
* callback function
|
||||||
|
*/
|
||||||
|
lpfc_nlp_put(ndlp);
|
||||||
|
|
||||||
mempool_free(pmb, phba->mbox_mem_pool);
|
mempool_free(pmb, phba->mbox_mem_pool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4336,26 +4408,29 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
|
||||||
mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
|
mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
|
||||||
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
|
if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
|
||||||
== MBX_NOT_FINISHED) {
|
== MBX_NOT_FINISHED) {
|
||||||
|
/* mailbox command not success, decrement ndlp
|
||||||
|
* reference count for this command
|
||||||
|
*/
|
||||||
|
lpfc_nlp_put(ndlp);
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
spin_lock_irq(shost->host_lock);
|
|
||||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
|
||||||
spin_unlock_irq(shost->host_lock);
|
|
||||||
|
|
||||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
||||||
"0253 Register VPI: Can't send mbox\n");
|
"0253 Register VPI: Can't send mbox\n");
|
||||||
|
goto mbox_err_exit;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
|
||||||
|
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
|
||||||
"0254 Register VPI: no memory\n");
|
"0254 Register VPI: no memory\n");
|
||||||
|
goto mbox_err_exit;
|
||||||
spin_lock_irq(shost->host_lock);
|
|
||||||
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
|
||||||
spin_unlock_irq(shost->host_lock);
|
|
||||||
lpfc_nlp_put(ndlp);
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
mbox_err_exit:
|
||||||
|
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||||
|
spin_lock_irq(shost->host_lock);
|
||||||
|
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
|
||||||
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4436,7 +4511,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
else
|
else
|
||||||
lpfc_do_scr_ns_plogi(phba, vport);
|
lpfc_do_scr_ns_plogi(phba, vport);
|
||||||
|
|
||||||
lpfc_nlp_put(ndlp); /* Free Fabric ndlp for vports */
|
/* Unconditionaly kick off releasing fabric node for vports */
|
||||||
|
lpfc_nlp_put(ndlp);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -149,7 +149,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock_irq(&phba->hbalock);
|
spin_lock_irq(&phba->hbalock);
|
||||||
evtp->evt_arg1 = ndlp;
|
/* We need to hold the node by incrementing the reference
|
||||||
|
* count until this queued work is done
|
||||||
|
*/
|
||||||
|
evtp->evt_arg1 = lpfc_nlp_get(ndlp);
|
||||||
evtp->evt = LPFC_EVT_DEV_LOSS;
|
evtp->evt = LPFC_EVT_DEV_LOSS;
|
||||||
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
list_add_tail(&evtp->evt_listp, &phba->work_list);
|
||||||
if (phba->work_wait)
|
if (phba->work_wait)
|
||||||
|
@ -300,12 +303,18 @@ lpfc_work_list_done(struct lpfc_hba *phba)
|
||||||
ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
|
ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
|
||||||
lpfc_els_retry_delay_handler(ndlp);
|
lpfc_els_retry_delay_handler(ndlp);
|
||||||
free_evt = 0; /* evt is part of ndlp */
|
free_evt = 0; /* evt is part of ndlp */
|
||||||
|
/* decrement the node reference count held
|
||||||
|
* for this queued work
|
||||||
|
*/
|
||||||
|
lpfc_nlp_put(ndlp);
|
||||||
break;
|
break;
|
||||||
case LPFC_EVT_DEV_LOSS:
|
case LPFC_EVT_DEV_LOSS:
|
||||||
ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
|
ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
|
||||||
lpfc_nlp_get(ndlp);
|
|
||||||
lpfc_dev_loss_tmo_handler(ndlp);
|
lpfc_dev_loss_tmo_handler(ndlp);
|
||||||
free_evt = 0;
|
free_evt = 0;
|
||||||
|
/* decrement the node reference count held for
|
||||||
|
* this queued work
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
break;
|
break;
|
||||||
case LPFC_EVT_ONLINE:
|
case LPFC_EVT_ONLINE:
|
||||||
|
@ -1176,6 +1185,9 @@ 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);
|
||||||
|
/* decrement the node reference count held for this callback
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1363,6 +1375,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
|
|
||||||
if (mb->mbxStatus) {
|
if (mb->mbxStatus) {
|
||||||
out:
|
out:
|
||||||
|
/* decrement the node reference count held for this
|
||||||
|
* callback function.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||||
kfree(mp);
|
kfree(mp);
|
||||||
|
@ -1414,6 +1429,9 @@ out:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* decrement the node reference count held for this
|
||||||
|
* callback function.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||||
kfree(mp);
|
kfree(mp);
|
||||||
|
@ -1661,13 +1679,14 @@ void
|
||||||
lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Use of lpfc_drop_node and UNUSED list. lpfc_drop_node should
|
* Use of lpfc_drop_node and UNUSED list: lpfc_drop_node should
|
||||||
* be used if we wish to issue the "last" lpfc_nlp_put() to remove
|
* be used if we wish to issue the "last" lpfc_nlp_put() to remove
|
||||||
* the ndlp from the vport. The ndlp resides on the UNUSED list
|
* the ndlp from the vport. The ndlp marked as UNUSED on the list
|
||||||
* until ALL other outstanding threads have completed. Thus, if a
|
* until ALL other outstanding threads have completed. We check
|
||||||
* ndlp is on the UNUSED list already, we should never do another
|
* that the ndlp not already in the UNUSED state before we proceed.
|
||||||
* lpfc_drop_node() on it.
|
|
||||||
*/
|
*/
|
||||||
|
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
|
||||||
|
return;
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
return;
|
return;
|
||||||
|
@ -2767,7 +2786,9 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||||
else
|
else
|
||||||
mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
|
mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
|
||||||
|
|
||||||
/* Mailbox took a reference to the node */
|
/* decrement the node reference count held for this callback
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
lpfc_nlp_put(ndlp);
|
||||||
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
||||||
kfree(mp);
|
kfree(mp);
|
||||||
|
|
|
@ -922,6 +922,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
|
||||||
NLP_STE_REG_LOGIN_ISSUE);
|
NLP_STE_REG_LOGIN_ISSUE);
|
||||||
return ndlp->nlp_state;
|
return ndlp->nlp_state;
|
||||||
}
|
}
|
||||||
|
/* decrement node reference count to the failed mbox
|
||||||
|
* command
|
||||||
|
*/
|
||||||
lpfc_nlp_put(ndlp);
|
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);
|
||||||
|
|
|
@ -2605,7 +2605,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
|
||||||
"1806 Mbox x%x failed. No vport\n",
|
"1806 Mbox x%x failed. No vport\n",
|
||||||
pmbox->mb.mbxCommand);
|
pmbox->mb.mbxCommand);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
return MBXERR_ERROR;
|
return MBX_NOT_FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue