Commit 43d781b9 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe
Browse files

RDMA: Allow fail of destroy CQ

Like any other verbs objects, CQ shouldn't fail during destroy, but
mlx5_ib didn't follow this contract with mixed IB verbs objects with
DEVX. Such mix causes to the situation where FW and kernel are fully
interdependent on the reference counting of each side.

Kernel verbs and drivers that don't have DEVX flows shouldn't fail.

Fixes: e39afe3d ("RDMA: Convert CQ allocations to be under core responsibility")
Link: https://lore.kernel.org/r/20200907120921.476363-7-leon@kernel.org


Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 7e3c66c9
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -319,6 +319,8 @@ EXPORT_SYMBOL(__ib_alloc_cq_any);
 */
void ib_free_cq(struct ib_cq *cq)
{
	int ret;

	if (WARN_ON_ONCE(atomic_read(&cq->usecnt)))
		return;
	if (WARN_ON_ONCE(cq->cqe_used))
@@ -340,8 +342,9 @@ void ib_free_cq(struct ib_cq *cq)

	rdma_dim_destroy(cq);
	trace_cq_free(cq);
	ret = cq->device->ops.destroy_cq(cq, NULL);
	WARN_ONCE(ret, "Destroy of kernel CQ shouldn't fail");
	rdma_restrack_del(&cq->res);
	cq->device->ops.destroy_cq(cq, NULL);
	kfree(cq->wc);
	kfree(cq);
}
+7 −2
Original line number Diff line number Diff line
@@ -2023,16 +2023,21 @@ EXPORT_SYMBOL(rdma_set_cq_moderation);

int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
{
	int ret;

	if (WARN_ON_ONCE(cq->shared))
		return -EOPNOTSUPP;

	if (atomic_read(&cq->usecnt))
		return -EBUSY;

	ret = cq->device->ops.destroy_cq(cq, udata);
	if (ret)
		return ret;

	rdma_restrack_del(&cq->res);
	cq->device->ops.destroy_cq(cq, udata);
	kfree(cq);
	return 0;
	return ret;
}
EXPORT_SYMBOL(ib_destroy_cq_user);

+2 −1
Original line number Diff line number Diff line
@@ -2803,7 +2803,7 @@ int bnxt_re_post_recv(struct ib_qp *ib_qp, const struct ib_recv_wr *wr,
}

/* Completion Queues */
void bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
{
	struct bnxt_re_cq *cq;
	struct bnxt_qplib_nq *nq;
@@ -2819,6 +2819,7 @@ void bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
	atomic_dec(&rdev->cq_count);
	nq->budget--;
	kfree(cq->cql);
	return 0;
}

int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
+1 −1
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ int bnxt_re_post_recv(struct ib_qp *qp, const struct ib_recv_wr *recv_wr,
		      const struct ib_recv_wr **bad_recv_wr);
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
		      struct ib_udata *udata);
void bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
int bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
int bnxt_re_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
int bnxt_re_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
+2 −1
Original line number Diff line number Diff line
@@ -967,7 +967,7 @@ int c4iw_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
	return !err || err == -ENODATA ? npolled : err;
}

void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
{
	struct c4iw_cq *chp;
	struct c4iw_ucontext *ucontext;
@@ -985,6 +985,7 @@ void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
		   ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx,
		   chp->destroy_skb, chp->wr_waitp);
	c4iw_put_wr_wait(chp->wr_waitp);
	return 0;
}

int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
Loading