aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-01-11 01:53:27 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-23 12:29:24 -0500
commitfa4066b672821d24cb7180b8d0434b01a7043172 (patch)
tree3a42b4c706b002a165c762f7a613052a0633903e
parentc95d6c6c2b0a303a113fd468efce7430d5b20eac (diff)
[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>
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c172
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c37
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c3
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c2
5 files changed, 157 insertions, 58 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 3759ae1dc5e7..92441ce610ed 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -561,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
561 if (vport->load_flag & FC_UNLOADING) 561 if (vport->load_flag & FC_UNLOADING)
562 goto out; 562 goto out;
563 563
564
565 if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { 564 if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
566 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 565 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
567 "0216 Link event during NS query\n"); 566 "0216 Link event during NS query\n");
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 8da6e8be9d83..c6b739dc6bc3 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -120,12 +120,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
120 pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 120 pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
121 if (pcmd) 121 if (pcmd)
122 pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); 122 pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
123 if (!pcmd || !pcmd->virt) { 123 if (!pcmd || !pcmd->virt)
124 kfree(pcmd); 124 goto els_iocb_free_pcmb_exit;
125
126 lpfc_sli_release_iocbq(phba, elsiocb);
127 return NULL;
128 }
129 125
130 INIT_LIST_HEAD(&pcmd->list); 126 INIT_LIST_HEAD(&pcmd->list);
131 127
@@ -135,13 +131,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
135 if (prsp) 131 if (prsp)
136 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 132 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
137 &prsp->phys); 133 &prsp->phys);
138 if (!prsp || !prsp->virt) { 134 if (!prsp || !prsp->virt)
139 kfree(prsp); 135 goto els_iocb_free_prsp_exit;
140 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
141 kfree(pcmd);
142 lpfc_sli_release_iocbq(phba, elsiocb);
143 return NULL;
144 }
145 INIT_LIST_HEAD(&prsp->list); 136 INIT_LIST_HEAD(&prsp->list);
146 } else { 137 } else {
147 prsp = NULL; 138 prsp = NULL;
@@ -152,15 +143,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
152 if (pbuflist) 143 if (pbuflist)
153 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 144 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
154 &pbuflist->phys); 145 &pbuflist->phys);
155 if (!pbuflist || !pbuflist->virt) { 146 if (!pbuflist || !pbuflist->virt)
156 lpfc_sli_release_iocbq(phba, elsiocb); 147 goto els_iocb_free_pbuf_exit;
157 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
158 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
159 kfree(pcmd);
160 kfree(prsp);
161 kfree(pbuflist);
162 return NULL;
163 }
164 148
165 INIT_LIST_HEAD(&pbuflist->list); 149 INIT_LIST_HEAD(&pbuflist->list);
166 150
@@ -205,7 +189,10 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
205 bpl->tus.w = le32_to_cpu(bpl->tus.w); 189 bpl->tus.w = le32_to_cpu(bpl->tus.w);
206 } 190 }
207 191
192 /* prevent preparing iocb with NULL ndlp reference */
208 elsiocb->context1 = lpfc_nlp_get(ndlp); 193 elsiocb->context1 = lpfc_nlp_get(ndlp);
194 if (!elsiocb->context1)
195 goto els_iocb_free_pbuf_exit;
209 elsiocb->context2 = pcmd; 196 elsiocb->context2 = pcmd;
210 elsiocb->context3 = pbuflist; 197 elsiocb->context3 = pbuflist;
211 elsiocb->retry = retry; 198 elsiocb->retry = retry;
@@ -231,8 +218,20 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
231 cmdSize); 218 cmdSize);
232 } 219 }
233 return elsiocb; 220 return elsiocb;
234}
235 221
222els_iocb_free_pbuf_exit:
223 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
224 kfree(pbuflist);
225
226els_iocb_free_prsp_exit:
227 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
228 kfree(prsp);
229
230els_iocb_free_pcmb_exit:
231 kfree(pcmd);
232 lpfc_sli_release_iocbq(phba, elsiocb);
233 return NULL;
234}
236 235
237static int 236static int
238lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) 237lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
@@ -513,6 +512,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
513 512
514 /* Check to see if link went down during discovery */ 513 /* Check to see if link went down during discovery */
515 if (lpfc_els_chk_latt(vport)) { 514 if (lpfc_els_chk_latt(vport)) {
515 /* One additional decrement on node reference count to
516 * trigger the release of the node
517 */
516 lpfc_nlp_put(ndlp); 518 lpfc_nlp_put(ndlp);
517 goto out; 519 goto out;
518 } 520 }
@@ -731,6 +733,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
731 } 733 }
732 734
733 if (lpfc_issue_els_flogi(vport, ndlp, 0)) { 735 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
736 /* This decrement of reference count to node shall kick off
737 * the release of the node.
738 */
734 lpfc_nlp_put(ndlp); 739 lpfc_nlp_put(ndlp);
735 } 740 }
736 return 1; 741 return 1;
@@ -754,7 +759,11 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
754 lpfc_dequeue_node(vport, ndlp); 759 lpfc_dequeue_node(vport, ndlp);
755 } 760 }
756 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { 761 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
762 /* decrement node reference count to trigger the release of
763 * the node.
764 */
757 lpfc_nlp_put(ndlp); 765 lpfc_nlp_put(ndlp);
766 return 0;
758 } 767 }
759 return 1; 768 return 1;
760} 769}
@@ -1557,6 +1566,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1557 ndlp->nlp_DID, ELS_CMD_SCR); 1566 ndlp->nlp_DID, ELS_CMD_SCR);
1558 1567
1559 if (!elsiocb) { 1568 if (!elsiocb) {
1569 /* This will trigger the release of the node just
1570 * allocated
1571 */
1560 lpfc_nlp_put(ndlp); 1572 lpfc_nlp_put(ndlp);
1561 return 1; 1573 return 1;
1562 } 1574 }
@@ -1578,10 +1590,17 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1578 phba->fc_stat.elsXmitSCR++; 1590 phba->fc_stat.elsXmitSCR++;
1579 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 1591 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
1580 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { 1592 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
1593 /* The additional lpfc_nlp_put will cause the following
1594 * lpfc_els_free_iocb routine to trigger the rlease of
1595 * the node.
1596 */
1581 lpfc_nlp_put(ndlp); 1597 lpfc_nlp_put(ndlp);
1582 lpfc_els_free_iocb(phba, elsiocb); 1598 lpfc_els_free_iocb(phba, elsiocb);
1583 return 1; 1599 return 1;
1584 } 1600 }
1601 /* This will cause the callback-function lpfc_cmpl_els_cmd to
1602 * trigger the release of node.
1603 */
1585 lpfc_nlp_put(ndlp); 1604 lpfc_nlp_put(ndlp);
1586 return 0; 1605 return 0;
1587} 1606}
@@ -1613,6 +1632,9 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1613 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, 1632 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1614 ndlp->nlp_DID, ELS_CMD_RNID); 1633 ndlp->nlp_DID, ELS_CMD_RNID);
1615 if (!elsiocb) { 1634 if (!elsiocb) {
1635 /* This will trigger the release of the node just
1636 * allocated
1637 */
1616 lpfc_nlp_put(ndlp); 1638 lpfc_nlp_put(ndlp);
1617 return 1; 1639 return 1;
1618 } 1640 }
@@ -1649,10 +1671,17 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1649 phba->fc_stat.elsXmitFARPR++; 1671 phba->fc_stat.elsXmitFARPR++;
1650 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; 1672 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
1651 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { 1673 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
1674 /* The additional lpfc_nlp_put will cause the following
1675 * lpfc_els_free_iocb routine to trigger the release of
1676 * the node.
1677 */
1652 lpfc_nlp_put(ndlp); 1678 lpfc_nlp_put(ndlp);
1653 lpfc_els_free_iocb(phba, elsiocb); 1679 lpfc_els_free_iocb(phba, elsiocb);
1654 return 1; 1680 return 1;
1655 } 1681 }
1682 /* This will cause the callback-function lpfc_cmpl_els_cmd to
1683 * trigger the release of the node.
1684 */
1656 lpfc_nlp_put(ndlp); 1685 lpfc_nlp_put(ndlp);
1657 return 0; 1686 return 0;
1658} 1687}
@@ -1712,7 +1741,10 @@ lpfc_els_retry_delay(unsigned long ptr)
1712 return; 1741 return;
1713 } 1742 }
1714 1743
1715 evtp->evt_arg1 = ndlp; 1744 /* We need to hold the node by incrementing the reference
1745 * count until the queued work is done
1746 */
1747 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
1716 evtp->evt = LPFC_EVT_ELS_RETRY; 1748 evtp->evt = LPFC_EVT_ELS_RETRY;
1717 list_add_tail(&evtp->evt_listp, &phba->work_list); 1749 list_add_tail(&evtp->evt_listp, &phba->work_list);
1718 if (phba->work_wait) 1750 if (phba->work_wait)
@@ -2190,6 +2222,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2190 * thread, just unregister the RPI. 2222 * thread, just unregister the RPI.
2191 */ 2223 */
2192 lpfc_unreg_rpi(vport, ndlp); 2224 lpfc_unreg_rpi(vport, ndlp);
2225 } else {
2226 /* Indicate the node has already released, should
2227 * not reference to it from within lpfc_els_free_iocb.
2228 */
2229 cmdiocb->context1 = NULL;
2193 } 2230 }
2194 } 2231 }
2195 lpfc_els_free_iocb(phba, cmdiocb); 2232 lpfc_els_free_iocb(phba, cmdiocb);
@@ -2208,7 +2245,6 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2208 mempool_free(pmb, phba->mbox_mem_pool); 2245 mempool_free(pmb, phba->mbox_mem_pool);
2209 if (ndlp) { 2246 if (ndlp) {
2210 lpfc_nlp_put(ndlp); 2247 lpfc_nlp_put(ndlp);
2211
2212 /* This is the end of the default RPI cleanup logic for this 2248 /* This is the end of the default RPI cleanup logic for this
2213 * ndlp. If no other discovery threads are using this ndlp. 2249 * ndlp. If no other discovery threads are using this ndlp.
2214 * we should free all resources associated with it. 2250 * we should free all resources associated with it.
@@ -2236,11 +2272,13 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2236 if (cmdiocb->context_un.mbox) 2272 if (cmdiocb->context_un.mbox)
2237 mbox = cmdiocb->context_un.mbox; 2273 mbox = cmdiocb->context_un.mbox;
2238 2274
2239 /* First determine if this is a LS_RJT cmpl */ 2275 /* First determine if this is a LS_RJT cmpl. Note, this callback
2276 * function can have cmdiocb->contest1 (ndlp) field set to NULL.
2277 */
2240 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); 2278 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
2241 if (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT) { 2279 if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
2242 /* A LS_RJT associated with Default RPI cleanup 2280 /* A LS_RJT associated with Default RPI cleanup has its own
2243 * has its own seperate code path. 2281 * seperate code path.
2244 */ 2282 */
2245 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) 2283 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
2246 ls_rjt = 1; 2284 ls_rjt = 1;
@@ -2257,8 +2295,14 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2257 mempool_free(mbox, phba->mbox_mem_pool); 2295 mempool_free(mbox, phba->mbox_mem_pool);
2258 } 2296 }
2259 if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) 2297 if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
2260 if (lpfc_nlp_not_used(ndlp)) 2298 if (lpfc_nlp_not_used(ndlp)) {
2261 ndlp = NULL; 2299 ndlp = NULL;
2300 /* Indicate the node has already released,
2301 * should not reference to it from within
2302 * the routine lpfc_els_free_iocb.
2303 */
2304 cmdiocb->context1 = NULL;
2305 }
2262 goto out; 2306 goto out;
2263 } 2307 }
2264 2308
@@ -2302,14 +2346,27 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2302 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, 2346 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
2303 ndlp->nlp_rpi); 2347 ndlp->nlp_rpi);
2304 2348
2305 if (lpfc_nlp_not_used(ndlp)) 2349 if (lpfc_nlp_not_used(ndlp)) {
2306 ndlp = NULL; 2350 ndlp = NULL;
2351 /* Indicate node has already been released,
2352 * should not reference to it from within
2353 * the routine lpfc_els_free_iocb.
2354 */
2355 cmdiocb->context1 = NULL;
2356 }
2307 } else { 2357 } else {
2308 /* Do not drop node for lpfc_els_abort'ed ELS cmds */ 2358 /* Do not drop node for lpfc_els_abort'ed ELS cmds */
2309 if (!lpfc_error_lost_link(irsp) && 2359 if (!lpfc_error_lost_link(irsp) &&
2310 ndlp->nlp_flag & NLP_ACC_REGLOGIN) { 2360 ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
2311 if (lpfc_nlp_not_used(ndlp)) 2361 if (lpfc_nlp_not_used(ndlp)) {
2312 ndlp = NULL; 2362 ndlp = NULL;
2363 /* Indicate node has already been
2364 * released, should not reference
2365 * to it from within the routine
2366 * lpfc_els_free_iocb.
2367 */
2368 cmdiocb->context1 = NULL;
2369 }
2313 } 2370 }
2314 } 2371 }
2315 mp = (struct lpfc_dmabuf *) mbox->context1; 2372 mp = (struct lpfc_dmabuf *) mbox->context1;
@@ -2331,7 +2388,12 @@ out:
2331 * resources. 2388 * resources.
2332 */ 2389 */
2333 if (ls_rjt) 2390 if (ls_rjt)
2334 lpfc_nlp_not_used(ndlp); 2391 if (lpfc_nlp_not_used(ndlp))
2392 /* Indicate node has already been released,
2393 * should not reference to it from within
2394 * the routine lpfc_els_free_iocb.
2395 */
2396 cmdiocb->context1 = NULL;
2335 } 2397 }
2336 2398
2337 lpfc_els_free_iocb(phba, cmdiocb); 2399 lpfc_els_free_iocb(phba, cmdiocb);
@@ -3292,7 +3354,10 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3292 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, 3354 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
3293 lpfc_max_els_tries, ndlp, 3355 lpfc_max_els_tries, ndlp,
3294 ndlp->nlp_DID, ELS_CMD_ACC); 3356 ndlp->nlp_DID, ELS_CMD_ACC);
3357
3358 /* Decrement the ndlp reference count from previous mbox command */
3295 lpfc_nlp_put(ndlp); 3359 lpfc_nlp_put(ndlp);
3360
3296 if (!elsiocb) 3361 if (!elsiocb)
3297 return; 3362 return;
3298 3363
@@ -3375,11 +3440,13 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3375 mbox->context2 = lpfc_nlp_get(ndlp); 3440 mbox->context2 = lpfc_nlp_get(ndlp);
3376 mbox->vport = vport; 3441 mbox->vport = vport;
3377 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; 3442 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
3378 if (lpfc_sli_issue_mbox (phba, mbox, MBX_NOWAIT) 3443 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
3379 != MBX_NOT_FINISHED) 3444 != MBX_NOT_FINISHED)
3380 /* Mbox completion will send ELS Response */ 3445 /* Mbox completion will send ELS Response */
3381 return 0; 3446 return 0;
3382 3447 /* Decrement reference count used for the failed mbox
3448 * command.
3449 */
3383 lpfc_nlp_put(ndlp); 3450 lpfc_nlp_put(ndlp);
3384 mempool_free(mbox, phba->mbox_mem_pool); 3451 mempool_free(mbox, phba->mbox_mem_pool);
3385 } 3452 }
@@ -4284,7 +4351,6 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4284 spin_lock_irq(shost->host_lock); 4351 spin_lock_irq(shost->host_lock);
4285 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; 4352 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4286 spin_unlock_irq(shost->host_lock); 4353 spin_unlock_irq(shost->host_lock);
4287 lpfc_nlp_put(ndlp);
4288 4354
4289 if (mb->mbxStatus) { 4355 if (mb->mbxStatus) {
4290 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, 4356 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)
4317 else 4383 else
4318 lpfc_do_scr_ns_plogi(phba, vport); 4384 lpfc_do_scr_ns_plogi(phba, vport);
4319 } 4385 }
4386
4387 /* Now, we decrement the ndlp reference count held for this
4388 * callback function
4389 */
4390 lpfc_nlp_put(ndlp);
4391
4320 mempool_free(pmb, phba->mbox_mem_pool); 4392 mempool_free(pmb, phba->mbox_mem_pool);
4321 return; 4393 return;
4322} 4394}
@@ -4336,26 +4408,29 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
4336 mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; 4408 mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
4337 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) 4409 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
4338 == MBX_NOT_FINISHED) { 4410 == MBX_NOT_FINISHED) {
4411 /* mailbox command not success, decrement ndlp
4412 * reference count for this command
4413 */
4414 lpfc_nlp_put(ndlp);
4339 mempool_free(mbox, phba->mbox_mem_pool); 4415 mempool_free(mbox, phba->mbox_mem_pool);
4340 spin_lock_irq(shost->host_lock);
4341 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4342 spin_unlock_irq(shost->host_lock);
4343 4416
4344 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4345 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, 4417 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
4346 "0253 Register VPI: Can't send mbox\n"); 4418 "0253 Register VPI: Can't send mbox\n");
4419 goto mbox_err_exit;
4347 } 4420 }
4348 } else { 4421 } else {
4349 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4350
4351 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, 4422 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
4352 "0254 Register VPI: no memory\n"); 4423 "0254 Register VPI: no memory\n");
4353 4424 goto mbox_err_exit;
4354 spin_lock_irq(shost->host_lock);
4355 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4356 spin_unlock_irq(shost->host_lock);
4357 lpfc_nlp_put(ndlp);
4358 } 4425 }
4426 return;
4427
4428mbox_err_exit:
4429 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4430 spin_lock_irq(shost->host_lock);
4431 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
4432 spin_unlock_irq(shost->host_lock);
4433 return;
4359} 4434}
4360 4435
4361static void 4436static void
@@ -4436,7 +4511,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4436 else 4511 else
4437 lpfc_do_scr_ns_plogi(phba, vport); 4512 lpfc_do_scr_ns_plogi(phba, vport);
4438 4513
4439 lpfc_nlp_put(ndlp); /* Free Fabric ndlp for vports */ 4514 /* Unconditionaly kick off releasing fabric node for vports */
4515 lpfc_nlp_put(ndlp);
4440 } 4516 }
4441 4517
4442out: 4518out:
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 644d96012d56..dc042bd97baa 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -149,7 +149,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
149 return; 149 return;
150 150
151 spin_lock_irq(&phba->hbalock); 151 spin_lock_irq(&phba->hbalock);
152 evtp->evt_arg1 = ndlp; 152 /* We need to hold the node by incrementing the reference
153 * count until this queued work is done
154 */
155 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
153 evtp->evt = LPFC_EVT_DEV_LOSS; 156 evtp->evt = LPFC_EVT_DEV_LOSS;
154 list_add_tail(&evtp->evt_listp, &phba->work_list); 157 list_add_tail(&evtp->evt_listp, &phba->work_list);
155 if (phba->work_wait) 158 if (phba->work_wait)
@@ -300,12 +303,18 @@ lpfc_work_list_done(struct lpfc_hba *phba)
300 ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1); 303 ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
301 lpfc_els_retry_delay_handler(ndlp); 304 lpfc_els_retry_delay_handler(ndlp);
302 free_evt = 0; /* evt is part of ndlp */ 305 free_evt = 0; /* evt is part of ndlp */
306 /* decrement the node reference count held
307 * for this queued work
308 */
309 lpfc_nlp_put(ndlp);
303 break; 310 break;
304 case LPFC_EVT_DEV_LOSS: 311 case LPFC_EVT_DEV_LOSS:
305 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1); 312 ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
306 lpfc_nlp_get(ndlp);
307 lpfc_dev_loss_tmo_handler(ndlp); 313 lpfc_dev_loss_tmo_handler(ndlp);
308 free_evt = 0; 314 free_evt = 0;
315 /* decrement the node reference count held for
316 * this queued work
317 */
309 lpfc_nlp_put(ndlp); 318 lpfc_nlp_put(ndlp);
310 break; 319 break;
311 case LPFC_EVT_ONLINE: 320 case LPFC_EVT_ONLINE:
@@ -1176,6 +1185,9 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1176 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1185 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1177 kfree(mp); 1186 kfree(mp);
1178 mempool_free(pmb, phba->mbox_mem_pool); 1187 mempool_free(pmb, phba->mbox_mem_pool);
1188 /* decrement the node reference count held for this callback
1189 * function.
1190 */
1179 lpfc_nlp_put(ndlp); 1191 lpfc_nlp_put(ndlp);
1180 1192
1181 return; 1193 return;
@@ -1363,6 +1375,9 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1363 1375
1364 if (mb->mbxStatus) { 1376 if (mb->mbxStatus) {
1365out: 1377out:
1378 /* decrement the node reference count held for this
1379 * callback function.
1380 */
1366 lpfc_nlp_put(ndlp); 1381 lpfc_nlp_put(ndlp);
1367 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1382 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1368 kfree(mp); 1383 kfree(mp);
@@ -1414,6 +1429,9 @@ out:
1414 goto out; 1429 goto out;
1415 } 1430 }
1416 1431
1432 /* decrement the node reference count held for this
1433 * callback function.
1434 */
1417 lpfc_nlp_put(ndlp); 1435 lpfc_nlp_put(ndlp);
1418 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1436 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1419 kfree(mp); 1437 kfree(mp);
@@ -1661,13 +1679,14 @@ void
1661lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 1679lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1662{ 1680{
1663 /* 1681 /*
1664 * Use of lpfc_drop_node and UNUSED list. lpfc_drop_node should 1682 * Use of lpfc_drop_node and UNUSED list: lpfc_drop_node should
1665 * be used if we wish to issue the "last" lpfc_nlp_put() to remove 1683 * be used if we wish to issue the "last" lpfc_nlp_put() to remove
1666 * the ndlp from the vport. The ndlp resides on the UNUSED list 1684 * the ndlp from the vport. The ndlp marked as UNUSED on the list
1667 * until ALL other outstanding threads have completed. Thus, if a 1685 * until ALL other outstanding threads have completed. We check
1668 * ndlp is on the UNUSED list already, we should never do another 1686 * that the ndlp not already in the UNUSED state before we proceed.
1669 * lpfc_drop_node() on it.
1670 */ 1687 */
1688 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
1689 return;
1671 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 1690 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1672 lpfc_nlp_put(ndlp); 1691 lpfc_nlp_put(ndlp);
1673 return; 1692 return;
@@ -2767,7 +2786,9 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2767 else 2786 else
2768 mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); 2787 mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
2769 2788
2770 /* Mailbox took a reference to the node */ 2789 /* decrement the node reference count held for this callback
2790 * function.
2791 */
2771 lpfc_nlp_put(ndlp); 2792 lpfc_nlp_put(ndlp);
2772 lpfc_mbuf_free(phba, mp->virt, mp->phys); 2793 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2773 kfree(mp); 2794 kfree(mp);
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 783659aa2102..4a0e3406e37a 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -922,6 +922,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
922 NLP_STE_REG_LOGIN_ISSUE); 922 NLP_STE_REG_LOGIN_ISSUE);
923 return ndlp->nlp_state; 923 return ndlp->nlp_state;
924 } 924 }
925 /* decrement node reference count to the failed mbox
926 * command
927 */
925 lpfc_nlp_put(ndlp); 928 lpfc_nlp_put(ndlp);
926 mp = (struct lpfc_dmabuf *) mbox->context1; 929 mp = (struct lpfc_dmabuf *) mbox->context1;
927 lpfc_mbuf_free(phba, mp->virt, mp->phys); 930 lpfc_mbuf_free(phba, mp->virt, mp->phys);
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 584c5451641f..fdd01e384e36 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2605,7 +2605,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2605 "1806 Mbox x%x failed. No vport\n", 2605 "1806 Mbox x%x failed. No vport\n",
2606 pmbox->mb.mbxCommand); 2606 pmbox->mb.mbxCommand);
2607 dump_stack(); 2607 dump_stack();
2608 return MBXERR_ERROR; 2608 return MBX_NOT_FINISHED;
2609 } 2609 }
2610 } 2610 }
2611 2611