Loading drivers/scsi/lpfc/lpfc_ct.c +0 −1 Original line number Diff line number Diff line Loading @@ -561,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (vport->load_flag & FC_UNLOADING) goto out; if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0216 Link event during NS query\n"); Loading drivers/scsi/lpfc/lpfc_els.c +124 −48 Original line number Diff line number Diff line Loading @@ -120,12 +120,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (pcmd) pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); if (!pcmd || !pcmd->virt) { kfree(pcmd); lpfc_sli_release_iocbq(phba, elsiocb); return NULL; } if (!pcmd || !pcmd->virt) goto els_iocb_free_pcmb_exit; INIT_LIST_HEAD(&pcmd->list); Loading @@ -135,13 +131,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, if (prsp) prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &prsp->phys); if (!prsp || !prsp->virt) { kfree(prsp); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); kfree(pcmd); lpfc_sli_release_iocbq(phba, elsiocb); return NULL; } if (!prsp || !prsp->virt) goto els_iocb_free_prsp_exit; INIT_LIST_HEAD(&prsp->list); } else { prsp = NULL; Loading @@ -152,15 +143,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, if (pbuflist) pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pbuflist->phys); if (!pbuflist || !pbuflist->virt) { lpfc_sli_release_iocbq(phba, elsiocb); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); lpfc_mbuf_free(phba, prsp->virt, prsp->phys); kfree(pcmd); kfree(prsp); kfree(pbuflist); return NULL; } if (!pbuflist || !pbuflist->virt) goto els_iocb_free_pbuf_exit; INIT_LIST_HEAD(&pbuflist->list); Loading Loading @@ -205,7 +189,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, bpl->tus.w = le32_to_cpu(bpl->tus.w); } /* prevent preparing iocb with NULL ndlp reference */ elsiocb->context1 = lpfc_nlp_get(ndlp); if (!elsiocb->context1) goto els_iocb_free_pbuf_exit; elsiocb->context2 = pcmd; elsiocb->context3 = pbuflist; elsiocb->retry = retry; Loading @@ -231,8 +218,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, cmdSize); } 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 lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) Loading Loading @@ -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 */ if (lpfc_els_chk_latt(vport)) { /* One additional decrement on node reference count to * trigger the release of the node */ lpfc_nlp_put(ndlp); goto out; } Loading Loading @@ -731,6 +733,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport) } 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); } return 1; Loading @@ -754,7 +759,11 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) lpfc_dequeue_node(vport, ndlp); } if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { /* decrement node reference count to trigger the release of * the node. */ lpfc_nlp_put(ndlp); return 0; } return 1; } Loading Loading @@ -1557,6 +1566,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) ndlp->nlp_DID, ELS_CMD_SCR); if (!elsiocb) { /* This will trigger the release of the node just * allocated */ lpfc_nlp_put(ndlp); return 1; } Loading @@ -1578,10 +1590,17 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) phba->fc_stat.elsXmitSCR++; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 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_els_free_iocb(phba, elsiocb); return 1; } /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of node. */ lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -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, ndlp->nlp_DID, ELS_CMD_RNID); if (!elsiocb) { /* This will trigger the release of the node just * allocated */ lpfc_nlp_put(ndlp); return 1; } Loading Loading @@ -1649,10 +1671,17 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) phba->fc_stat.elsXmitFARPR++; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 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_els_free_iocb(phba, elsiocb); return 1; } /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of the node. */ lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1712,7 +1741,10 @@ lpfc_els_retry_delay(unsigned long ptr) 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; list_add_tail(&evtp->evt_listp, &phba->work_list); if (phba->work_wait) Loading Loading @@ -2190,6 +2222,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * thread, just unregister the RPI. */ 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); Loading @@ -2208,7 +2245,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mempool_free(pmb, phba->mbox_mem_pool); if (ndlp) { lpfc_nlp_put(ndlp); /* This is the end of the default RPI cleanup logic for this * ndlp. If no other discovery threads are using this ndlp. * we should free all resources associated with it. Loading Loading @@ -2236,11 +2272,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (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); if (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT) { /* A LS_RJT associated with Default RPI cleanup * has its own seperate code path. if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { /* A LS_RJT associated with Default RPI cleanup has its own * seperate code path. */ if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) ls_rjt = 1; Loading @@ -2257,8 +2295,14 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, mempool_free(mbox, phba->mbox_mem_pool); } if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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; } Loading Loading @@ -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_rpi); if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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 { /* Do not drop node for lpfc_els_abort'ed ELS cmds */ if (!lpfc_error_lost_link(irsp) && ndlp->nlp_flag & NLP_ACC_REGLOGIN) { if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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; Loading @@ -2331,7 +2388,12 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * resources. */ 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); Loading Loading @@ -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, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); /* Decrement the ndlp reference count from previous mbox command */ lpfc_nlp_put(ndlp); if (!elsiocb) return; Loading Loading @@ -3379,7 +3444,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, != MBX_NOT_FINISHED) /* Mbox completion will send ELS Response */ return 0; /* Decrement reference count used for the failed mbox * command. */ lpfc_nlp_put(ndlp); mempool_free(mbox, phba->mbox_mem_pool); } Loading Loading @@ -4284,7 +4351,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; spin_unlock_irq(shost->host_lock); lpfc_nlp_put(ndlp); if (mb->mbxStatus) { lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, Loading Loading @@ -4317,6 +4383,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else 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); return; } Loading @@ -4336,26 +4408,29 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == 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); 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, "0253 Register VPI: Can't send mbox\n"); goto mbox_err_exit; } } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, "0254 Register VPI: no memory\n"); goto mbox_err_exit; } 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); lpfc_nlp_put(ndlp); } return; } static void Loading Loading @@ -4436,7 +4511,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, else 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: Loading drivers/scsi/lpfc/lpfc_hbadisc.c +29 −8 Original line number Diff line number Diff line Loading @@ -149,7 +149,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) return; 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; list_add_tail(&evtp->evt_listp, &phba->work_list); if (phba->work_wait) Loading Loading @@ -300,12 +303,18 @@ lpfc_work_list_done(struct lpfc_hba *phba) ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); lpfc_els_retry_delay_handler(ndlp); free_evt = 0; /* evt is part of ndlp */ /* decrement the node reference count held * for this queued work */ lpfc_nlp_put(ndlp); break; case LPFC_EVT_DEV_LOSS: ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); lpfc_nlp_get(ndlp); lpfc_dev_loss_tmo_handler(ndlp); free_evt = 0; /* decrement the node reference count held for * this queued work */ lpfc_nlp_put(ndlp); break; case LPFC_EVT_ONLINE: Loading Loading @@ -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); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); /* decrement the node reference count held for this callback * function. */ lpfc_nlp_put(ndlp); return; Loading Loading @@ -1363,6 +1375,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (mb->mbxStatus) { out: /* decrement the node reference count held for this * callback function. */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -1414,6 +1429,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) goto out; } /* decrement the node reference count held for this * callback function. */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -1661,13 +1679,14 @@ void 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 * the ndlp from the vport. The ndlp resides on the UNUSED list * until ALL other outstanding threads have completed. Thus, if a * ndlp is on the UNUSED list already, we should never do another * lpfc_drop_node() on it. * the ndlp from the vport. The ndlp marked as UNUSED on the list * until ALL other outstanding threads have completed. We check * that the ndlp not already in the UNUSED state before we proceed. */ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) return; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); lpfc_nlp_put(ndlp); return; Loading Loading @@ -2767,7 +2786,9 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else 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_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading drivers/scsi/lpfc/lpfc_nportdisc.c +3 −0 Original line number Diff line number Diff line Loading @@ -922,6 +922,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, NLP_STE_REG_LOGIN_ISSUE); return ndlp->nlp_state; } /* decrement node reference count to the failed mbox * command */ lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *) mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); Loading drivers/scsi/lpfc/lpfc_sli.c +1 −1 Original line number Diff line number Diff line Loading @@ -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", pmbox->mb.mbxCommand); dump_stack(); return MBXERR_ERROR; return MBX_NOT_FINISHED; } } Loading Loading
drivers/scsi/lpfc/lpfc_ct.c +0 −1 Original line number Diff line number Diff line Loading @@ -561,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (vport->load_flag & FC_UNLOADING) goto out; if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0216 Link event during NS query\n"); Loading
drivers/scsi/lpfc/lpfc_els.c +124 −48 Original line number Diff line number Diff line Loading @@ -120,12 +120,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (pcmd) pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); if (!pcmd || !pcmd->virt) { kfree(pcmd); lpfc_sli_release_iocbq(phba, elsiocb); return NULL; } if (!pcmd || !pcmd->virt) goto els_iocb_free_pcmb_exit; INIT_LIST_HEAD(&pcmd->list); Loading @@ -135,13 +131,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, if (prsp) prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &prsp->phys); if (!prsp || !prsp->virt) { kfree(prsp); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); kfree(pcmd); lpfc_sli_release_iocbq(phba, elsiocb); return NULL; } if (!prsp || !prsp->virt) goto els_iocb_free_prsp_exit; INIT_LIST_HEAD(&prsp->list); } else { prsp = NULL; Loading @@ -152,15 +143,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, if (pbuflist) pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pbuflist->phys); if (!pbuflist || !pbuflist->virt) { lpfc_sli_release_iocbq(phba, elsiocb); lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); lpfc_mbuf_free(phba, prsp->virt, prsp->phys); kfree(pcmd); kfree(prsp); kfree(pbuflist); return NULL; } if (!pbuflist || !pbuflist->virt) goto els_iocb_free_pbuf_exit; INIT_LIST_HEAD(&pbuflist->list); Loading Loading @@ -205,7 +189,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, bpl->tus.w = le32_to_cpu(bpl->tus.w); } /* prevent preparing iocb with NULL ndlp reference */ elsiocb->context1 = lpfc_nlp_get(ndlp); if (!elsiocb->context1) goto els_iocb_free_pbuf_exit; elsiocb->context2 = pcmd; elsiocb->context3 = pbuflist; elsiocb->retry = retry; Loading @@ -231,8 +218,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, cmdSize); } 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 lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) Loading Loading @@ -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 */ if (lpfc_els_chk_latt(vport)) { /* One additional decrement on node reference count to * trigger the release of the node */ lpfc_nlp_put(ndlp); goto out; } Loading Loading @@ -731,6 +733,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport) } 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); } return 1; Loading @@ -754,7 +759,11 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) lpfc_dequeue_node(vport, ndlp); } if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { /* decrement node reference count to trigger the release of * the node. */ lpfc_nlp_put(ndlp); return 0; } return 1; } Loading Loading @@ -1557,6 +1566,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) ndlp->nlp_DID, ELS_CMD_SCR); if (!elsiocb) { /* This will trigger the release of the node just * allocated */ lpfc_nlp_put(ndlp); return 1; } Loading @@ -1578,10 +1590,17 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) phba->fc_stat.elsXmitSCR++; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 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_els_free_iocb(phba, elsiocb); return 1; } /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of node. */ lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -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, ndlp->nlp_DID, ELS_CMD_RNID); if (!elsiocb) { /* This will trigger the release of the node just * allocated */ lpfc_nlp_put(ndlp); return 1; } Loading Loading @@ -1649,10 +1671,17 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) phba->fc_stat.elsXmitFARPR++; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 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_els_free_iocb(phba, elsiocb); return 1; } /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of the node. */ lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1712,7 +1741,10 @@ lpfc_els_retry_delay(unsigned long ptr) 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; list_add_tail(&evtp->evt_listp, &phba->work_list); if (phba->work_wait) Loading Loading @@ -2190,6 +2222,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * thread, just unregister the RPI. */ 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); Loading @@ -2208,7 +2245,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mempool_free(pmb, phba->mbox_mem_pool); if (ndlp) { lpfc_nlp_put(ndlp); /* This is the end of the default RPI cleanup logic for this * ndlp. If no other discovery threads are using this ndlp. * we should free all resources associated with it. Loading Loading @@ -2236,11 +2272,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (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); if (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT) { /* A LS_RJT associated with Default RPI cleanup * has its own seperate code path. if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { /* A LS_RJT associated with Default RPI cleanup has its own * seperate code path. */ if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) ls_rjt = 1; Loading @@ -2257,8 +2295,14 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, mempool_free(mbox, phba->mbox_mem_pool); } if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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; } Loading Loading @@ -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_rpi); if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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 { /* Do not drop node for lpfc_els_abort'ed ELS cmds */ if (!lpfc_error_lost_link(irsp) && ndlp->nlp_flag & NLP_ACC_REGLOGIN) { if (lpfc_nlp_not_used(ndlp)) if (lpfc_nlp_not_used(ndlp)) { 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; Loading @@ -2331,7 +2388,12 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * resources. */ 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); Loading Loading @@ -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, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); /* Decrement the ndlp reference count from previous mbox command */ lpfc_nlp_put(ndlp); if (!elsiocb) return; Loading Loading @@ -3379,7 +3444,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, != MBX_NOT_FINISHED) /* Mbox completion will send ELS Response */ return 0; /* Decrement reference count used for the failed mbox * command. */ lpfc_nlp_put(ndlp); mempool_free(mbox, phba->mbox_mem_pool); } Loading Loading @@ -4284,7 +4351,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; spin_unlock_irq(shost->host_lock); lpfc_nlp_put(ndlp); if (mb->mbxStatus) { lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, Loading Loading @@ -4317,6 +4383,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else 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); return; } Loading @@ -4336,26 +4408,29 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == 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); 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, "0253 Register VPI: Can't send mbox\n"); goto mbox_err_exit; } } else { lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, "0254 Register VPI: no memory\n"); goto mbox_err_exit; } 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); lpfc_nlp_put(ndlp); } return; } static void Loading Loading @@ -4436,7 +4511,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, else 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: Loading
drivers/scsi/lpfc/lpfc_hbadisc.c +29 −8 Original line number Diff line number Diff line Loading @@ -149,7 +149,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) return; 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; list_add_tail(&evtp->evt_listp, &phba->work_list); if (phba->work_wait) Loading Loading @@ -300,12 +303,18 @@ lpfc_work_list_done(struct lpfc_hba *phba) ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); lpfc_els_retry_delay_handler(ndlp); free_evt = 0; /* evt is part of ndlp */ /* decrement the node reference count held * for this queued work */ lpfc_nlp_put(ndlp); break; case LPFC_EVT_DEV_LOSS: ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); lpfc_nlp_get(ndlp); lpfc_dev_loss_tmo_handler(ndlp); free_evt = 0; /* decrement the node reference count held for * this queued work */ lpfc_nlp_put(ndlp); break; case LPFC_EVT_ONLINE: Loading Loading @@ -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); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); /* decrement the node reference count held for this callback * function. */ lpfc_nlp_put(ndlp); return; Loading Loading @@ -1363,6 +1375,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (mb->mbxStatus) { out: /* decrement the node reference count held for this * callback function. */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -1414,6 +1429,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) goto out; } /* decrement the node reference count held for this * callback function. */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -1661,13 +1679,14 @@ void 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 * the ndlp from the vport. The ndlp resides on the UNUSED list * until ALL other outstanding threads have completed. Thus, if a * ndlp is on the UNUSED list already, we should never do another * lpfc_drop_node() on it. * the ndlp from the vport. The ndlp marked as UNUSED on the list * until ALL other outstanding threads have completed. We check * that the ndlp not already in the UNUSED state before we proceed. */ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) return; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); lpfc_nlp_put(ndlp); return; Loading Loading @@ -2767,7 +2786,9 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) else 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_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading
drivers/scsi/lpfc/lpfc_nportdisc.c +3 −0 Original line number Diff line number Diff line Loading @@ -922,6 +922,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, NLP_STE_REG_LOGIN_ISSUE); return ndlp->nlp_state; } /* decrement node reference count to the failed mbox * command */ lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *) mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); Loading
drivers/scsi/lpfc/lpfc_sli.c +1 −1 Original line number Diff line number Diff line Loading @@ -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", pmbox->mb.mbxCommand); dump_stack(); return MBXERR_ERROR; return MBX_NOT_FINISHED; } } Loading