|
Daniel Wagner |
d56cdd |
From: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
d56cdd |
Date: Fri, 3 Dec 2021 16:26:36 -0800
|
|
Daniel Wagner |
d56cdd |
Subject: scsi: lpfc: Fix leaked lpfc_dmabuf mbox allocations with NPIV
|
|
Daniel Wagner |
d56cdd |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Daniel Wagner |
d56cdd |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
|
|
Daniel Wagner |
d56cdd |
Git-commit: f0d3919697492950f57a26a1093aee53880d669d
|
|
Daniel Wagner |
d56cdd |
References: bsc1192145
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
During rmmod testing, messages appeared indicating lpfc_mbuf_pool entries
|
|
Daniel Wagner |
d56cdd |
were still busy. This situation was only seen doing rmmod after at least 1
|
|
Daniel Wagner |
d56cdd |
vport (NPIV) instance was created and destroyed. The number of messages
|
|
Daniel Wagner |
d56cdd |
scaled with the number of vports created.
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
When a vport is created, it can receive a PLOGI from another initiator
|
|
Daniel Wagner |
d56cdd |
Nport. When this happens, the driver prepares to ack the PLOGI and
|
|
Daniel Wagner |
d56cdd |
prepares an RPI for registration (via mbx cmd) which includes an mbuf
|
|
Daniel Wagner |
d56cdd |
allocation. During the unsolicited PLOGI processing and after the RPI
|
|
Daniel Wagner |
d56cdd |
preparation, the driver recognizes it is one of the vport instances and
|
|
Daniel Wagner |
d56cdd |
decides to reject the PLOGI. During the LS_RJT preparation for the PLOGI,
|
|
Daniel Wagner |
d56cdd |
the mailbox struct allocated for RPI registration is freed, but the mbuf
|
|
Daniel Wagner |
d56cdd |
that was also allocated is not released.
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
Fix by freeing the mbuf with the mailbox struct in the LS_RJT path.
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
As part of the code review to figure the issue out a couple of other areas
|
|
Daniel Wagner |
d56cdd |
where found that also would not have released the mbuf. Those are cleaned
|
|
Daniel Wagner |
d56cdd |
up as well.
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
Link: https://lore.kernel.org/r/20211204002644.116455-2-jsmart2021@gmail.com
|
|
Daniel Wagner |
d56cdd |
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
d56cdd |
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
d56cdd |
Signed-off-by: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
d56cdd |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Daniel Wagner |
d56cdd |
Acked-by: Daniel Wagner <dwagner@suse.de>
|
|
Daniel Wagner |
d56cdd |
---
|
|
Daniel Wagner |
d56cdd |
drivers/scsi/lpfc/lpfc_els.c | 6 +++++-
|
|
Daniel Wagner |
d56cdd |
drivers/scsi/lpfc/lpfc_init.c | 8 ++++++--
|
|
Daniel Wagner |
d56cdd |
drivers/scsi/lpfc/lpfc_nportdisc.c | 6 ++++++
|
|
Daniel Wagner |
d56cdd |
3 files changed, 17 insertions(+), 3 deletions(-)
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
--- a/drivers/scsi/lpfc/lpfc_els.c
|
|
Daniel Wagner |
d56cdd |
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
|
Daniel Wagner |
d56cdd |
@@ -6851,6 +6851,7 @@ static int
|
|
Daniel Wagner |
d56cdd |
lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
|
|
Daniel Wagner |
d56cdd |
{
|
|
Daniel Wagner |
d56cdd |
LPFC_MBOXQ_t *mbox = NULL;
|
|
Daniel Wagner |
d56cdd |
+ struct lpfc_dmabuf *mp;
|
|
Daniel Wagner |
d56cdd |
int rc;
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
Daniel Wagner |
d56cdd |
@@ -6866,8 +6867,11 @@ lpfc_get_rdp_info(struct lpfc_hba *phba,
|
|
Daniel Wagner |
d56cdd |
mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
|
|
Daniel Wagner |
d56cdd |
mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
|
|
Daniel Wagner |
d56cdd |
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
|
Daniel Wagner |
d56cdd |
- if (rc == MBX_NOT_FINISHED)
|
|
Daniel Wagner |
d56cdd |
+ if (rc == MBX_NOT_FINISHED) {
|
|
Daniel Wagner |
d56cdd |
+ mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
|
|
Daniel Wagner |
d56cdd |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
d56cdd |
goto issue_mbox_fail;
|
|
Daniel Wagner |
d56cdd |
+ }
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
return 0;
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
--- a/drivers/scsi/lpfc/lpfc_init.c
|
|
Daniel Wagner |
d56cdd |
+++ b/drivers/scsi/lpfc/lpfc_init.c
|
|
Daniel Wagner |
d56cdd |
@@ -5278,8 +5278,10 @@ lpfc_sli4_async_link_evt(struct lpfc_hba
|
|
Daniel Wagner |
d56cdd |
*/
|
|
Daniel Wagner |
d56cdd |
if (!(phba->hba_flag & HBA_FCOE_MODE)) {
|
|
Daniel Wagner |
d56cdd |
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
|
|
Daniel Wagner |
d56cdd |
- if (rc == MBX_NOT_FINISHED)
|
|
Daniel Wagner |
d56cdd |
+ if (rc == MBX_NOT_FINISHED) {
|
|
Daniel Wagner |
d56cdd |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
d56cdd |
goto out_free_dmabuf;
|
|
Daniel Wagner |
d56cdd |
+ }
|
|
Daniel Wagner |
d56cdd |
return;
|
|
Daniel Wagner |
d56cdd |
}
|
|
Daniel Wagner |
d56cdd |
/*
|
|
Daniel Wagner |
d56cdd |
@@ -6242,8 +6244,10 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *
|
|
Daniel Wagner |
d56cdd |
}
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
|
|
Daniel Wagner |
d56cdd |
- if (rc == MBX_NOT_FINISHED)
|
|
Daniel Wagner |
d56cdd |
+ if (rc == MBX_NOT_FINISHED) {
|
|
Daniel Wagner |
d56cdd |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
d56cdd |
goto out_free_dmabuf;
|
|
Daniel Wagner |
d56cdd |
+ }
|
|
Daniel Wagner |
d56cdd |
return;
|
|
Daniel Wagner |
d56cdd |
|
|
Daniel Wagner |
d56cdd |
out_free_dmabuf:
|
|
Daniel Wagner |
d56cdd |
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
|
Daniel Wagner |
d56cdd |
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
|
Daniel Wagner |
d56cdd |
@@ -324,6 +324,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
|
|
Daniel Wagner |
d56cdd |
{
|
|
Daniel Wagner |
d56cdd |
struct lpfc_hba *phba = vport->phba;
|
|
Daniel Wagner |
d56cdd |
struct lpfc_dmabuf *pcmd;
|
|
Daniel Wagner |
d56cdd |
+ struct lpfc_dmabuf *mp;
|
|
Daniel Wagner |
d56cdd |
uint64_t nlp_portwwn = 0;
|
|
Daniel Wagner |
d56cdd |
uint32_t *lp;
|
|
Daniel Wagner |
d56cdd |
IOCB_t *icmd;
|
|
Daniel Wagner |
d56cdd |
@@ -568,6 +569,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport,
|
|
Daniel Wagner |
d56cdd |
* a default RPI.
|
|
Daniel Wagner |
d56cdd |
*/
|
|
Daniel Wagner |
d56cdd |
if (phba->sli_rev == LPFC_SLI_REV4) {
|
|
Daniel Wagner |
d56cdd |
+ mp = (struct lpfc_dmabuf *)login_mbox->ctx_buf;
|
|
Daniel Wagner |
d56cdd |
+ if (mp) {
|
|
Daniel Wagner |
d56cdd |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
d56cdd |
+ kfree(mp);
|
|
Daniel Wagner |
d56cdd |
+ }
|
|
Daniel Wagner |
d56cdd |
mempool_free(login_mbox, phba->mbox_mem_pool);
|
|
Daniel Wagner |
d56cdd |
login_mbox = NULL;
|
|
Daniel Wagner |
d56cdd |
} else {
|