summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2022-05-06 05:55:09 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2022-05-11 04:12:02 +0200
commitba3d58a1df460ba28bb5989ad7269ff48682375a (patch)
treef9ee99b36dab8837b87e0e84b69d9efd8c3d7402
parentscsi: lpfc: Fix element offset in __lpfc_sli_release_iocbq_s4() (diff)
downloadlinux-ba3d58a1df460ba28bb5989ad7269ff48682375a.tar.xz
linux-ba3d58a1df460ba28bb5989ad7269ff48682375a.zip
scsi: lpfc: Fill in missing ndlp kref puts in error paths
Code review, following every lpfc_nlp_get() call vs calls during error handling, discovered cases of missing put calls. Correct by adding ndlp kref puts in the respective error paths. Also added comments to several of the error paths to record relationships to reference counts. Link: https://lore.kernel.org/r/20220506035519.50908-3-jsmart2021@gmail.com Co-developed-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: Justin Tee <justin.tee@broadcom.com> Signed-off-by: James Smart <jsmart2021@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c15
-rw-r--r--drivers/scsi/lpfc/lpfc_nvme.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c6
4 files changed, 28 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 527f2c148e04..ace812ce857d 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -8725,19 +8725,18 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
elsiocb->cmd_cmpl = lpfc_cmpl_els_rrq;
elsiocb->ndlp = lpfc_nlp_get(ndlp);
- if (!elsiocb->ndlp) {
- lpfc_els_free_iocb(phba, elsiocb);
- return 1;
- }
+ if (!elsiocb->ndlp)
+ goto io_err;
ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
- if (ret == IOCB_ERROR)
+ if (ret == IOCB_ERROR) {
+ lpfc_nlp_put(ndlp);
goto io_err;
+ }
return 0;
io_err:
lpfc_els_free_iocb(phba, elsiocb);
- lpfc_nlp_put(ndlp);
return 1;
}
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 5e4822bf54f4..639f86635127 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -513,6 +513,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
lpfc_config_link(phba, link_mbox);
link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
link_mbox->vport = vport;
+
+ /* The default completion handling for CONFIG_LINK
+ * does not require the ndlp so no reference is needed.
+ */
link_mbox->ctx_ndlp = ndlp;
rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
@@ -633,6 +637,9 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
*/
login_mbox->mbox_cmpl = lpfc_defer_plogi_acc;
login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
+ if (!login_mbox->ctx_ndlp)
+ goto out;
+
login_mbox->context3 = save_iocb; /* For PLOGI ACC */
spin_lock_irq(&ndlp->lock);
@@ -641,8 +648,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
/* Start the ball rolling by issuing REG_LOGIN here */
rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED)
+ if (rc == MBX_NOT_FINISHED) {
+ lpfc_nlp_put(ndlp);
goto out;
+ }
lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
return 1;
@@ -1099,8 +1108,10 @@ lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport,
ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag);
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
- if (rc == MBX_NOT_FINISHED)
+ if (rc == MBX_NOT_FINISHED) {
+ lpfc_nlp_put(ndlp);
mempool_free(pmb, phba->mbox_mem_pool);
+ }
}
}
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c
index 376f6c0265c0..3aebd01e07fd 100644
--- a/drivers/scsi/lpfc/lpfc_nvme.c
+++ b/drivers/scsi/lpfc/lpfc_nvme.c
@@ -2357,6 +2357,11 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
rpinfo.dev_loss_tmo = vport->cfg_devloss_tmo;
spin_lock_irq(&ndlp->lock);
+
+ /* If an oldrport exists, so does the ndlp reference. If not
+ * a new reference is needed because either the node has never
+ * been registered or it's been unregistered and getting deleted.
+ */
oldrport = lpfc_ndlp_get_nrport(ndlp);
if (oldrport) {
prev_ndlp = oldrport->ndlp;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index d2900ac8de9d..fe4eb36426df 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -20684,8 +20684,12 @@ lpfc_cleanup_pending_mbox(struct lpfc_vport *vport)
mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
if (mb->u.mb.mbxCommand == MBX_REG_LOGIN64) {
act_mbx_ndlp = (struct lpfc_nodelist *)mb->ctx_ndlp;
- /* Put reference count for delayed processing */
+
+ /* This reference is local to this routine. The
+ * reference is removed at routine exit.
+ */
act_mbx_ndlp = lpfc_nlp_get(act_mbx_ndlp);
+
/* Unregister the RPI when mailbox complete */
mb->mbox_flag |= LPFC_MBX_IMED_UNREG;
}