| From 535005ca8e5e71918d64074032f4b9d4fef8981e Mon Sep 17 00:00:00 2001 |
| From: Yuval Avnery <yuvalav@mellanox.com> |
| Date: Tue, 22 Jan 2019 09:02:05 +0200 |
| Subject: IB/core: Destroy QP if XRC QP fails |
| |
| From: Yuval Avnery <yuvalav@mellanox.com> |
| |
| commit 535005ca8e5e71918d64074032f4b9d4fef8981e upstream. |
| |
| The open-coded variant missed destroy of SELinux created QP, reuse already |
| existing ib_detroy_qp() call and use this opportunity to clean |
| ib_create_qp() from double prints and unclear exit paths. |
| |
| Reported-by: Parav Pandit <parav@mellanox.com> |
| Fixes: d291f1a65232 ("IB/core: Enforce PKey security on QPs") |
| Signed-off-by: Yuval Avnery <yuvalav@mellanox.com> |
| Reviewed-by: Parav Pandit <parav@mellanox.com> |
| Reviewed-by: Daniel Jurgens <danielj@mellanox.com> |
| Signed-off-by: Leon Romanovsky <leonro@mellanox.com> |
| Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/infiniband/core/verbs.c | 41 +++++++++++++++++++++++----------------- |
| 1 file changed, 24 insertions(+), 17 deletions(-) |
| |
| --- a/drivers/infiniband/core/verbs.c |
| +++ b/drivers/infiniband/core/verbs.c |
| @@ -1106,8 +1106,8 @@ struct ib_qp *ib_open_qp(struct ib_xrcd |
| } |
| EXPORT_SYMBOL(ib_open_qp); |
| |
| -static struct ib_qp *ib_create_xrc_qp(struct ib_qp *qp, |
| - struct ib_qp_init_attr *qp_init_attr) |
| +static struct ib_qp *create_xrc_qp(struct ib_qp *qp, |
| + struct ib_qp_init_attr *qp_init_attr) |
| { |
| struct ib_qp *real_qp = qp; |
| |
| @@ -1122,10 +1122,10 @@ static struct ib_qp *ib_create_xrc_qp(st |
| |
| qp = __ib_open_qp(real_qp, qp_init_attr->event_handler, |
| qp_init_attr->qp_context); |
| - if (!IS_ERR(qp)) |
| - __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp); |
| - else |
| - real_qp->device->ops.destroy_qp(real_qp); |
| + if (IS_ERR(qp)) |
| + return qp; |
| + |
| + __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp); |
| return qp; |
| } |
| |
| @@ -1156,10 +1156,8 @@ struct ib_qp *ib_create_qp(struct ib_pd |
| return qp; |
| |
| ret = ib_create_qp_security(qp, device); |
| - if (ret) { |
| - ib_destroy_qp(qp); |
| - return ERR_PTR(ret); |
| - } |
| + if (ret) |
| + goto err; |
| |
| qp->real_qp = qp; |
| qp->qp_type = qp_init_attr->qp_type; |
| @@ -1172,8 +1170,15 @@ struct ib_qp *ib_create_qp(struct ib_pd |
| INIT_LIST_HEAD(&qp->sig_mrs); |
| qp->port = 0; |
| |
| - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) |
| - return ib_create_xrc_qp(qp, qp_init_attr); |
| + if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { |
| + struct ib_qp *xrc_qp = create_xrc_qp(qp, qp_init_attr); |
| + |
| + if (IS_ERR(xrc_qp)) { |
| + ret = PTR_ERR(xrc_qp); |
| + goto err; |
| + } |
| + return xrc_qp; |
| + } |
| |
| qp->event_handler = qp_init_attr->event_handler; |
| qp->qp_context = qp_init_attr->qp_context; |
| @@ -1200,11 +1205,8 @@ struct ib_qp *ib_create_qp(struct ib_pd |
| |
| if (qp_init_attr->cap.max_rdma_ctxs) { |
| ret = rdma_rw_init_mrs(qp, qp_init_attr); |
| - if (ret) { |
| - pr_err("failed to init MR pool ret= %d\n", ret); |
| - ib_destroy_qp(qp); |
| - return ERR_PTR(ret); |
| - } |
| + if (ret) |
| + goto err; |
| } |
| |
| /* |
| @@ -1217,6 +1219,11 @@ struct ib_qp *ib_create_qp(struct ib_pd |
| device->attrs.max_sge_rd); |
| |
| return qp; |
| + |
| +err: |
| + ib_destroy_qp(qp); |
| + return ERR_PTR(ret); |
| + |
| } |
| EXPORT_SYMBOL(ib_create_qp); |
| |