lkml.org 
[lkml]   [2022]   [Jan]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.16 23/52] scsi: lpfc: Fix leaked lpfc_dmabuf mbox allocations with NPIV
    Date
    From: James Smart <jsmart2021@gmail.com>

    [ Upstream commit f0d3919697492950f57a26a1093aee53880d669d ]

    During rmmod testing, messages appeared indicating lpfc_mbuf_pool entries
    were still busy. This situation was only seen doing rmmod after at least 1
    vport (NPIV) instance was created and destroyed. The number of messages
    scaled with the number of vports created.

    When a vport is created, it can receive a PLOGI from another initiator
    Nport. When this happens, the driver prepares to ack the PLOGI and
    prepares an RPI for registration (via mbx cmd) which includes an mbuf
    allocation. During the unsolicited PLOGI processing and after the RPI
    preparation, the driver recognizes it is one of the vport instances and
    decides to reject the PLOGI. During the LS_RJT preparation for the PLOGI,
    the mailbox struct allocated for RPI registration is freed, but the mbuf
    that was also allocated is not released.

    Fix by freeing the mbuf with the mailbox struct in the LS_RJT path.

    As part of the code review to figure the issue out a couple of other areas
    where found that also would not have released the mbuf. Those are cleaned
    up as well.

    Link: https://lore.kernel.org/r/20211204002644.116455-2-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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/lpfc/lpfc_els.c | 6 +++++-
    drivers/scsi/lpfc/lpfc_init.c | 8 ++++++--
    drivers/scsi/lpfc/lpfc_nportdisc.c | 6 ++++++
    3 files changed, 17 insertions(+), 3 deletions(-)

    diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
    index e83453bea2aee..5c10416c1c75a 100644
    --- a/drivers/scsi/lpfc/lpfc_els.c
    +++ b/drivers/scsi/lpfc/lpfc_els.c
    @@ -6899,6 +6899,7 @@ static int
    lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
    {
    LPFC_MBOXQ_t *mbox = NULL;
    + struct lpfc_dmabuf *mp;
    int rc;

    mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
    @@ -6914,8 +6915,11 @@ lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
    mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
    mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
    rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
    - if (rc == MBX_NOT_FINISHED)
    + if (rc == MBX_NOT_FINISHED) {
    + mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
    + lpfc_mbuf_free(phba, mp->virt, mp->phys);
    goto issue_mbox_fail;
    + }

    return 0;

    diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
    index ba17a8f740a95..7628b0634c57a 100644
    --- a/drivers/scsi/lpfc/lpfc_init.c
    +++ b/drivers/scsi/lpfc/lpfc_init.c
    @@ -5373,8 +5373,10 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
    */
    if (!(phba->hba_flag & HBA_FCOE_MODE)) {
    rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
    - if (rc == MBX_NOT_FINISHED)
    + if (rc == MBX_NOT_FINISHED) {
    + lpfc_mbuf_free(phba, mp->virt, mp->phys);
    goto out_free_dmabuf;
    + }
    return;
    }
    /*
    @@ -6337,8 +6339,10 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
    }

    rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
    - if (rc == MBX_NOT_FINISHED)
    + if (rc == MBX_NOT_FINISHED) {
    + lpfc_mbuf_free(phba, mp->virt, mp->phys);
    goto out_free_dmabuf;
    + }
    return;

    out_free_dmabuf:
    diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
    index 27263f02ab9f6..7d717a4ac14d1 100644
    --- a/drivers/scsi/lpfc/lpfc_nportdisc.c
    +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
    @@ -322,6 +322,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
    {
    struct lpfc_hba *phba = vport->phba;
    struct lpfc_dmabuf *pcmd;
    + struct lpfc_dmabuf *mp;
    uint64_t nlp_portwwn = 0;
    uint32_t *lp;
    IOCB_t *icmd;
    @@ -571,6 +572,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
    * a default RPI.
    */
    if (phba->sli_rev == LPFC_SLI_REV4) {
    + mp = (struct lpfc_dmabuf *)login_mbox->ctx_buf;
    + if (mp) {
    + lpfc_mbuf_free(phba, mp->virt, mp->phys);
    + kfree(mp);
    + }
    mempool_free(login_mbox, phba->mbox_mem_pool);
    login_mbox = NULL;
    } else {
    --
    2.34.1
    \
     
     \ /
      Last update: 2022-01-17 18:00    [W:3.362 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site