Daniel Wagner f87571
From: James Smart <jsmart2021@gmail.com>
Daniel Wagner f87571
Date: Fri, 14 May 2021 12:55:52 -0700
Daniel Wagner f87571
Subject: scsi: lpfc: Add ndlp kref accounting for resume RPI path
Michal Kubecek 9a3a83
Patch-mainline: v5.14-rc1
Daniel Wagner f87571
Git-commit: 1037e4b4f81dc4ddf928e0ca2f1b182efdfdcc9d
Daniel Wagner f87571
References: bsc#1186451
Daniel Wagner f87571
Daniel Wagner f87571
The driver is crashing due to a bad pointer during driver load due in an
Daniel Wagner f87571
adisc acc receive routine. The driver is missing node get/put in the
Daniel Wagner f87571
mbx_resume_rpi paths.
Daniel Wagner f87571
Daniel Wagner f87571
Fix by adding the proper gets and puts into the resume_rpi path.
Daniel Wagner f87571
Daniel Wagner f87571
Link: https://lore.kernel.org/r/20210514195559.119853-5-jsmart2021@gmail.com
Daniel Wagner f87571
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Daniel Wagner f87571
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Daniel Wagner f87571
Signed-off-by: James Smart <jsmart2021@gmail.com>
Daniel Wagner f87571
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Daniel Wagner f87571
Acked-by: Daniel Wagner <dwagner@suse.de>
Daniel Wagner f87571
---
Daniel Wagner f87571
 drivers/scsi/lpfc/lpfc_nportdisc.c |    4 ++++
Daniel Wagner f87571
 drivers/scsi/lpfc/lpfc_sli.c       |   23 ++++++++++++++++++++++-
Daniel Wagner f87571
 2 files changed, 26 insertions(+), 1 deletion(-)
Daniel Wagner f87571
Daniel Wagner f87571
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
Daniel Wagner f87571
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
Daniel Wagner f87571
@@ -662,6 +662,10 @@ lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba
Daniel Wagner f87571
 		lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
Daniel Wagner f87571
 			ndlp, NULL);
Daniel Wagner f87571
 	}
Daniel Wagner f87571
+
Daniel Wagner f87571
+	/* This nlp_put pairs with lpfc_sli4_resume_rpi */
Daniel Wagner f87571
+	lpfc_nlp_put(ndlp);
Daniel Wagner f87571
+
Daniel Wagner f87571
 	kfree(elsiocb);
Daniel Wagner f87571
 	mempool_free(mboxq, phba->mbox_mem_pool);
Daniel Wagner f87571
 }
Daniel Wagner f87571
--- a/drivers/scsi/lpfc/lpfc_sli.c
Daniel Wagner f87571
+++ b/drivers/scsi/lpfc/lpfc_sli.c
Daniel Wagner f87571
@@ -2679,6 +2679,12 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *
Daniel Wagner f87571
 		}
Daniel Wagner f87571
 	}
Daniel Wagner f87571
 
Daniel Wagner f87571
+	/* This nlp_put pairs with lpfc_sli4_resume_rpi */
Daniel Wagner f87571
+	if (pmb->u.mb.mbxCommand == MBX_RESUME_RPI) {
Daniel Wagner f87571
+		ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
Daniel Wagner f87571
+		lpfc_nlp_put(ndlp);
Daniel Wagner f87571
+	}
Daniel Wagner f87571
+
Daniel Wagner f87571
 	/* Check security permission status on INIT_LINK mailbox command */
Daniel Wagner f87571
 	if ((pmb->u.mb.mbxCommand == MBX_INIT_LINK) &&
Daniel Wagner f87571
 	    (pmb->u.mb.mbxStatus == MBXERR_SEC_NO_PERMISSION))
Daniel Wagner f87571
@@ -19038,14 +19044,28 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelis
Daniel Wagner f87571
 	if (!mboxq)
Daniel Wagner f87571
 		return -ENOMEM;
Daniel Wagner f87571
 
Daniel Wagner f87571
+	/* If cmpl assigned, then this nlp_get pairs with
Daniel Wagner f87571
+	 * lpfc_mbx_cmpl_resume_rpi.
Daniel Wagner f87571
+	 *
Daniel Wagner f87571
+	 * Else cmpl is NULL, then this nlp_get pairs with
Daniel Wagner f87571
+	 * lpfc_sli_def_mbox_cmpl.
Daniel Wagner f87571
+	 */
Daniel Wagner f87571
+	if (!lpfc_nlp_get(ndlp)) {
Daniel Wagner f87571
+		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
Daniel Wagner f87571
+				"2122 %s: Failed to get nlp ref\n",
Daniel Wagner f87571
+				__func__);
Daniel Wagner f87571
+		mempool_free(mboxq, phba->mbox_mem_pool);
Daniel Wagner f87571
+		return -EIO;
Daniel Wagner f87571
+	}
Daniel Wagner f87571
+
Daniel Wagner f87571
 	/* Post all rpi memory regions to the port. */
Daniel Wagner f87571
 	lpfc_resume_rpi(mboxq, ndlp);
Daniel Wagner f87571
 	if (cmpl) {
Daniel Wagner f87571
 		mboxq->mbox_cmpl = cmpl;
Daniel Wagner f87571
 		mboxq->ctx_buf = arg;
Daniel Wagner f87571
-		mboxq->ctx_ndlp = ndlp;
Daniel Wagner f87571
 	} else
Daniel Wagner f87571
 		mboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
Daniel Wagner f87571
+	mboxq->ctx_ndlp = ndlp;
Daniel Wagner f87571
 	mboxq->vport = ndlp->vport;
Daniel Wagner f87571
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
Daniel Wagner f87571
 	if (rc == MBX_NOT_FINISHED) {
Daniel Wagner f87571
@@ -19053,6 +19073,7 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelis
Daniel Wagner f87571
 				"2010 Resume RPI Mailbox failed "
Daniel Wagner f87571
 				"status %d, mbxStatus x%x\n", rc,
Daniel Wagner f87571
 				bf_get(lpfc_mqe_status, &mboxq->u.mqe));
Daniel Wagner f87571
+		lpfc_nlp_put(ndlp);
Daniel Wagner f87571
 		mempool_free(mboxq, phba->mbox_mem_pool);
Daniel Wagner f87571
 		return -EIO;
Daniel Wagner f87571
 	}