Skip to content

Commit 093f87d

Browse files
Leon Romanovskygregkh
authored andcommitted
RDMA: Allow fail of destroy CQ
[ Upstream commit 43d781b ] 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: e39afe3 ("RDMA: Convert CQ allocations to be under core responsibility") Link: https://lore.kernel.org/r/20200907120921.476363-7-leon@kernel.org Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 590b3cc commit 093f87d

31 files changed

Lines changed: 66 additions & 37 deletions

drivers/infiniband/core/cq.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ EXPORT_SYMBOL(__ib_alloc_cq_any);
319319
*/
320320
void ib_free_cq(struct ib_cq *cq)
321321
{
322+
int ret;
323+
322324
if (WARN_ON_ONCE(atomic_read(&cq->usecnt)))
323325
return;
324326
if (WARN_ON_ONCE(cq->cqe_used))
@@ -340,8 +342,9 @@ void ib_free_cq(struct ib_cq *cq)
340342

341343
rdma_dim_destroy(cq);
342344
trace_cq_free(cq);
345+
ret = cq->device->ops.destroy_cq(cq, NULL);
346+
WARN_ONCE(ret, "Destroy of kernel CQ shouldn't fail");
343347
rdma_restrack_del(&cq->res);
344-
cq->device->ops.destroy_cq(cq, NULL);
345348
kfree(cq->wc);
346349
kfree(cq);
347350
}

drivers/infiniband/core/verbs.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,16 +2011,21 @@ EXPORT_SYMBOL(rdma_set_cq_moderation);
20112011

20122012
int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
20132013
{
2014+
int ret;
2015+
20142016
if (WARN_ON_ONCE(cq->shared))
20152017
return -EOPNOTSUPP;
20162018

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

2022+
ret = cq->device->ops.destroy_cq(cq, udata);
2023+
if (ret)
2024+
return ret;
2025+
20202026
rdma_restrack_del(&cq->res);
2021-
cq->device->ops.destroy_cq(cq, udata);
20222027
kfree(cq);
2023-
return 0;
2028+
return ret;
20242029
}
20252030
EXPORT_SYMBOL(ib_destroy_cq_user);
20262031

drivers/infiniband/hw/bnxt_re/ib_verbs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2800,7 +2800,7 @@ int bnxt_re_post_recv(struct ib_qp *ib_qp, const struct ib_recv_wr *wr,
28002800
}
28012801

28022802
/* Completion Queues */
2803-
void bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
2803+
int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
28042804
{
28052805
struct bnxt_re_cq *cq;
28062806
struct bnxt_qplib_nq *nq;
@@ -2816,6 +2816,7 @@ void bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
28162816
atomic_dec(&rdev->cq_count);
28172817
nq->budget--;
28182818
kfree(cq->cql);
2819+
return 0;
28192820
}
28202821

28212822
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,

drivers/infiniband/hw/bnxt_re/ib_verbs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ int bnxt_re_post_recv(struct ib_qp *qp, const struct ib_recv_wr *recv_wr,
193193
const struct ib_recv_wr **bad_recv_wr);
194194
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
195195
struct ib_udata *udata);
196-
void bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
196+
int bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
197197
int bnxt_re_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
198198
int bnxt_re_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
199199
struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *pd, int mr_access_flags);

drivers/infiniband/hw/cxgb4/cq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ int c4iw_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
967967
return !err || err == -ENODATA ? npolled : err;
968968
}
969969

970-
void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
970+
int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
971971
{
972972
struct c4iw_cq *chp;
973973
struct c4iw_ucontext *ucontext;
@@ -985,6 +985,7 @@ void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
985985
ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx,
986986
chp->destroy_skb, chp->wr_waitp);
987987
c4iw_put_wr_wait(chp->wr_waitp);
988+
return 0;
988989
}
989990

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

drivers/infiniband/hw/cxgb4/iw_cxgb4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
992992
struct ib_udata *udata);
993993
struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
994994
int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
995-
void c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
995+
int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
996996
int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
997997
struct ib_udata *udata);
998998
int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);

drivers/infiniband/hw/efa/efa.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
139139
struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
140140
struct ib_qp_init_attr *init_attr,
141141
struct ib_udata *udata);
142-
void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
142+
int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
143143
int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
144144
struct ib_udata *udata);
145145
struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,

drivers/infiniband/hw/efa/efa_verbs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ static int efa_destroy_cq_idx(struct efa_dev *dev, int cq_idx)
843843
return efa_com_destroy_cq(&dev->edev, &params);
844844
}
845845

846-
void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
846+
int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
847847
{
848848
struct efa_dev *dev = to_edev(ibcq->device);
849849
struct efa_cq *cq = to_ecq(ibcq);
@@ -856,6 +856,7 @@ void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
856856
efa_destroy_cq_idx(dev, cq->cq_idx);
857857
efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
858858
DMA_FROM_DEVICE);
859+
return 0;
859860
}
860861

861862
static int cq_mmap_entries_setup(struct efa_dev *dev, struct efa_cq *cq,

drivers/infiniband/hw/hns/hns_roce_cq.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
311311
return ret;
312312
}
313313

314-
void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
314+
int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
315315
{
316316
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
317317
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
@@ -322,6 +322,7 @@ void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
322322
free_cq_buf(hr_dev, hr_cq);
323323
free_cq_db(hr_dev, hr_cq, udata);
324324
free_cqc(hr_dev, hr_cq);
325+
return 0;
325326
}
326327

327328
void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)

drivers/infiniband/hw/hns/hns_roce_device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ struct hns_roce_hw {
930930
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
931931
int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
932932
struct ib_udata *udata);
933-
void (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
933+
int (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
934934
int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
935935
int (*init_eq)(struct hns_roce_dev *hr_dev);
936936
void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
@@ -1247,7 +1247,7 @@ int to_hr_qp_type(int qp_type);
12471247
int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
12481248
struct ib_udata *udata);
12491249

1250-
void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
1250+
int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
12511251
int hns_roce_db_map_user(struct hns_roce_ucontext *context,
12521252
struct ib_udata *udata, unsigned long virt,
12531253
struct hns_roce_db *db);

0 commit comments

Comments
 (0)