OSDN Git Service

RDMA/qedr: Fix potential memory leak in __qedr_alloc_mr()
authorJianglei Nie <niejianglei2021@163.com>
Thu, 14 Jul 2022 06:15:05 +0000 (14:15 +0800)
committerLeon Romanovsky <leonro@nvidia.com>
Mon, 18 Jul 2022 11:16:10 +0000 (14:16 +0300)
__qedr_alloc_mr() allocates a memory chunk for "mr->info.pbl_table" with
init_mr_info(). When rdma_alloc_tid() and rdma_register_tid() fail, "mr"
is released while "mr->info.pbl_table" is not released, which will lead
to a memory leak.

We should release the "mr->info.pbl_table" with qedr_free_pbl() when error
occurs to fix the memory leak.

Fixes: e0290cce6ac0 ("qedr: Add support for memory registeration verbs")
Link: https://lore.kernel.org/r/20220714061505.2342759-1-niejianglei2021@163.com
Signed-off-by: Jianglei Nie <niejianglei2021@163.com>
Acked-by: Michal KalderonĀ <michal.kalderon@marvell.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/qedr/verbs.c

index f0f43b6..3ecb472 100644 (file)
@@ -3082,7 +3082,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
                else
                        DP_ERR(dev, "roce alloc tid returned error %d\n", rc);
 
-               goto err0;
+               goto err1;
        }
 
        /* Index only, 18 bit long, lkey = itid << 8 | key */
@@ -3106,7 +3106,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
        rc = dev->ops->rdma_register_tid(dev->rdma_ctx, &mr->hw_mr);
        if (rc) {
                DP_ERR(dev, "roce register tid returned an error %d\n", rc);
-               goto err1;
+               goto err2;
        }
 
        mr->ibmr.lkey = mr->hw_mr.itid << 8 | mr->hw_mr.key;
@@ -3115,8 +3115,10 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd,
        DP_DEBUG(dev, QEDR_MSG_MR, "alloc frmr: %x\n", mr->ibmr.lkey);
        return mr;
 
-err1:
+err2:
        dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid);
+err1:
+       qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table);
 err0:
        kfree(mr);
        return ERR_PTR(rc);