lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 458/757] RDMA/qedr: Fix resource leak in qedr_create_qp
    Date
    From: Keita Suzuki <keitasuzuki.park@sslab.ics.keio.ac.jp>

    [ Upstream commit 3e45410fe3c202ffb619f301beff0644f717e132 ]

    When xa_insert() fails, the acquired resource in qedr_create_qp should
    also be freed. However, current implementation does not handle the error.

    Fix this by adding a new goto label that calls qedr_free_qp_resources.

    Fixes: 1212767e23bb ("qedr: Add wrapping generic structure for qpidr and adjust idr routines.")
    Link: https://lore.kernel.org/r/20200911125159.4577-1-keitasuzuki.park@sslab.ics.keio.ac.jp
    Signed-off-by: Keita Suzuki <keitasuzuki.park@sslab.ics.keio.ac.jp>
    Acked-by: Michal Kalderon <michal.kalderon@marvell.com>
    Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/hw/qedr/verbs.c | 52 ++++++++++++++++--------------
    1 file changed, 27 insertions(+), 25 deletions(-)

    diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
    index db6be39834128..10536cce120e8 100644
    --- a/drivers/infiniband/hw/qedr/verbs.c
    +++ b/drivers/infiniband/hw/qedr/verbs.c
    @@ -2113,6 +2113,28 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev,
    return rc;
    }

    +static int qedr_free_qp_resources(struct qedr_dev *dev, struct qedr_qp *qp,
    + struct ib_udata *udata)
    +{
    + struct qedr_ucontext *ctx =
    + rdma_udata_to_drv_context(udata, struct qedr_ucontext,
    + ibucontext);
    + int rc;
    +
    + if (qp->qp_type != IB_QPT_GSI) {
    + rc = dev->ops->rdma_destroy_qp(dev->rdma_ctx, qp->qed_qp);
    + if (rc)
    + return rc;
    + }
    +
    + if (qp->create_type == QEDR_QP_CREATE_USER)
    + qedr_cleanup_user(dev, ctx, qp);
    + else
    + qedr_cleanup_kernel(dev, qp);
    +
    + return 0;
    +}
    +
    struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
    struct ib_qp_init_attr *attrs,
    struct ib_udata *udata)
    @@ -2159,19 +2181,21 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd,
    rc = qedr_create_kernel_qp(dev, qp, ibpd, attrs);

    if (rc)
    - goto err;
    + goto out_free_qp;

    qp->ibqp.qp_num = qp->qp_id;

    if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
    rc = xa_insert(&dev->qps, qp->qp_id, qp, GFP_KERNEL);
    if (rc)
    - goto err;
    + goto out_free_qp_resources;
    }

    return &qp->ibqp;

    -err:
    +out_free_qp_resources:
    + qedr_free_qp_resources(dev, qp, udata);
    +out_free_qp:
    kfree(qp);

    return ERR_PTR(-EFAULT);
    @@ -2672,28 +2696,6 @@ int qedr_query_qp(struct ib_qp *ibqp,
    return rc;
    }

    -static int qedr_free_qp_resources(struct qedr_dev *dev, struct qedr_qp *qp,
    - struct ib_udata *udata)
    -{
    - struct qedr_ucontext *ctx =
    - rdma_udata_to_drv_context(udata, struct qedr_ucontext,
    - ibucontext);
    - int rc;
    -
    - if (qp->qp_type != IB_QPT_GSI) {
    - rc = dev->ops->rdma_destroy_qp(dev->rdma_ctx, qp->qed_qp);
    - if (rc)
    - return rc;
    - }
    -
    - if (qp->create_type == QEDR_QP_CREATE_USER)
    - qedr_cleanup_user(dev, ctx, qp);
    - else
    - qedr_cleanup_kernel(dev, qp);
    -
    - return 0;
    -}
    -
    int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
    {
    struct qedr_qp *qp = get_qedr_qp(ibqp);
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-10-27 17:10    [W:4.078 / U:1.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site