]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
RDMA: Allow fail of destroy CQ
authorLeon Romanovsky <leonro@mellanox.com>
Mon, 7 Sep 2020 12:09:18 +0000 (15:09 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Wed, 9 Sep 2020 17:14:29 +0000 (14:14 -0300)
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: e39afe3d6dbd ("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>
31 files changed:
drivers/infiniband/core/cq.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/cxgb4/cq.c
drivers/infiniband/hw/cxgb4/iw_cxgb4.h
drivers/infiniband/hw/efa/efa.h
drivers/infiniband/hw/efa/efa_verbs.c
drivers/infiniband/hw/hns/hns_roce_cq.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx5/cq.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/qedr/verbs.h
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
drivers/infiniband/sw/rdmavt/cq.c
drivers/infiniband/sw/rdmavt/cq.h
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/sw/siw/siw_verbs.c
drivers/infiniband/sw/siw/siw_verbs.h
include/rdma/ib_verbs.h

index ab556407803c5396cf544afc091a433f48d7391d..11edf7308eac08071ccb66bfe0aed3757e0db800 100644 (file)
@@ -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);
 }
index 41e2e35fa0902d7f4c3aee386f5a1b569c0f9a97..93503f10bcbb4c669c5df50e5895481cc7fcbc4a 100644 (file)
@@ -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);
 
index cb5074575ba94c0c3683f1e4c9854daa14851dde..4f07011e04eb5981098afc71c2d34d6b26df67fd 100644 (file)
@@ -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,
index 7ca2328094661a6871a9b1795b54f01695e4a63c..9a8130b79256ddaf4eddfcfade28d3c693189dea 100644 (file)
@@ -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);
index 352b8af1998a5907ba5f9d13d37f26d35144e982..28349ed50885408eb8032373304e1e7019685245 100644 (file)
@@ -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,
index fa91e80869c008068b44b50cadb6602cdbc76040..dc65811e6a93d4b1b8e5b88179c374486fb897ee 100644 (file)
@@ -992,7 +992,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start,
                                           struct ib_udata *udata);
 struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc);
 int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
-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);
 int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                   struct ib_udata *udata);
 int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
index 6b06ce87fbfcdeaffd4136f72384f53234f0688d..64ae8ba6a7f65e3922b62e18f6fce68da287ef40 100644 (file)
@@ -139,7 +139,7 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
 struct ib_qp *efa_create_qp(struct ib_pd *ibpd,
                            struct ib_qp_init_attr *init_attr,
                            struct ib_udata *udata);
-void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
+int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
 int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                  struct ib_udata *udata);
 struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
index a03e3514bd8af000bd6bd2ed3be6d34b52aeeccb..57910bcfc5723f69cd402126f736ad897798d114 100644 (file)
@@ -973,7 +973,7 @@ static int efa_destroy_cq_idx(struct efa_dev *dev, int cq_idx)
        return efa_com_destroy_cq(&dev->edev, &params);
 }
 
-void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct efa_dev *dev = to_edev(ibcq->device);
        struct efa_cq *cq = to_ecq(ibcq);
@@ -986,6 +986,7 @@ void efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
        efa_destroy_cq_idx(dev, cq->cq_idx);
        efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
                        DMA_FROM_DEVICE);
+       return 0;
 }
 
 static int cq_mmap_entries_setup(struct efa_dev *dev, struct efa_cq *cq,
index e87d616f798829887b65671bfded667dc29a5232..c5acf3332519b1e0f27f37ce8444d19f53ff9580 100644 (file)
@@ -311,7 +311,7 @@ err_cq_buf:
        return ret;
 }
 
-void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 {
        struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
        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)
        free_cq_buf(hr_dev, hr_cq);
        free_cq_db(hr_dev, hr_cq, udata);
        free_cqc(hr_dev, hr_cq);
+       return 0;
 }
 
 void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
index 462a6a5cd92a94ab2798c320ed7e2743f016252d..30290a7ce286ac123b155d36795f5bd66e15e435 100644 (file)
@@ -931,7 +931,7 @@ struct hns_roce_hw {
        int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
        int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
                        struct ib_udata *udata);
-       void (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
+       int (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
        int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
        int (*init_eq)(struct hns_roce_dev *hr_dev);
        void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
@@ -1251,7 +1251,7 @@ int to_hr_qp_type(int qp_type);
 int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
                       struct ib_udata *udata);
 
-void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
+int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
 int hns_roce_db_map_user(struct hns_roce_ucontext *context,
                         struct ib_udata *udata, unsigned long virt,
                         struct hns_roce_db *db);
index 7e4b63c520e0dc546eeb44f6d7f89c809fe1f1f3..96c14e5fb7ba34daed6ec3c034a1156e5dee6c42 100644 (file)
@@ -3572,7 +3572,7 @@ int hns_roce_v1_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
        return 0;
 }
 
-static void hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct hns_roce_dev *hr_dev = to_hr_dev(ibcq->device);
        struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
@@ -3603,6 +3603,7 @@ static void hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
                }
                wait_time++;
        }
+       return 0;
 }
 
 static void set_eq_cons_index_v1(struct hns_roce_eq *eq, int req_not)
index c0f796cb6e5e303b2535e41d816c8d5f7b448614..6f40d1d82a25d0047c6e604fd858c569e4d1b40c 100644 (file)
@@ -1053,7 +1053,7 @@ void i40iw_cq_wq_destroy(struct i40iw_device *iwdev, struct i40iw_sc_cq *cq)
  * @ib_cq: cq pointer
  * @udata: user data or NULL for kernel object
  */
-static void i40iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+static int i40iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 {
        struct i40iw_cq *iwcq;
        struct i40iw_device *iwdev;
@@ -1065,6 +1065,7 @@ static void i40iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
        i40iw_cq_wq_destroy(iwdev, cq);
        cq_free_resources(iwdev, iwcq);
        i40iw_rem_devusecount(iwdev);
+       return 0;
 }
 
 /**
index 8a3436994f809750be5352aab3adf9c180a35d3b..ee50dd823a8e8dc6baa5e96c03f769504c7f1228 100644 (file)
@@ -475,7 +475,7 @@ out:
        return err;
 }
 
-void mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
+int mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 {
        struct mlx4_ib_dev *dev = to_mdev(cq->device);
        struct mlx4_ib_cq *mcq = to_mcq(cq);
@@ -495,6 +495,7 @@ void mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
                mlx4_db_free(dev->dev, &mcq->db);
        }
        ib_umem_release(mcq->umem);
+       return 0;
 }
 
 static void dump_cqe(void *cqe)
index 392a5a7c2a31e98a2130335e3a3d4db49e30cb00..32a024f765eac2bd3cd804b2e3cbd2b35bda0a79 100644 (file)
@@ -742,7 +742,7 @@ int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
 int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
 int mlx4_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                      struct ib_udata *udata);
-void mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
+int mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
 int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
 void __mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
index b318bde2e565f2c5b8376f1bd5d312e39d05c7a0..35e5bbb44d3d8e8bd332e20ed1d24d9a1ea399c1 100644 (file)
@@ -1024,16 +1024,21 @@ err_cqb:
        return err;
 }
 
-void mlx5_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
+int mlx5_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 {
        struct mlx5_ib_dev *dev = to_mdev(cq->device);
        struct mlx5_ib_cq *mcq = to_mcq(cq);
+       int ret;
+
+       ret = mlx5_core_destroy_cq(dev->mdev, &mcq->mcq);
+       if (ret)
+               return ret;
 
-       mlx5_core_destroy_cq(dev->mdev, &mcq->mcq);
        if (udata)
                destroy_cq_user(mcq, udata);
        else
                destroy_cq_kernel(dev, mcq);
+       return 0;
 }
 
 static int is_equal_rsn(struct mlx5_cqe64 *cqe64, u32 rsn)
index b7b00e9e180b3c77e85d16189099bdc072bda623..0a65f7ba40c43af4d9b65821e7731fcc6c2f053f 100644 (file)
@@ -1151,7 +1151,7 @@ int mlx5_ib_read_wqe_srq(struct mlx5_ib_srq *srq, int wqe_index, void *buffer,
                         size_t buflen, size_t *bc);
 int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                      struct ib_udata *udata);
-void mlx5_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
+int mlx5_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
 int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
 int mlx5_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
index 5d1e17214f0c39d0e99b9724ad772a558c4695fb..4624b975fee29e97d47131d3739f3e443773d2c4 100644 (file)
@@ -792,7 +792,7 @@ out:
        return ret;
 }
 
-static void mthca_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
+static int mthca_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 {
        if (udata) {
                struct mthca_ucontext *context =
@@ -811,6 +811,7 @@ static void mthca_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
                                    to_mcq(cq)->set_ci_db_index);
        }
        mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
+       return 0;
 }
 
 static inline u32 convert_access(int acc)
index ed8c89c0b3e8bdf74c1b5cf661d42e3222b6d82a..b24437619412ea4750764d790b4751ab62060975 100644 (file)
@@ -1057,7 +1057,7 @@ static void ocrdma_flush_cq(struct ocrdma_cq *cq)
        spin_unlock_irqrestore(&cq->cq_lock, flags);
 }
 
-void ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+int ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
        struct ocrdma_eq *eq = NULL;
@@ -1082,6 +1082,7 @@ void ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
                                ocrdma_get_db_addr(dev, pdid),
                                dev->nic_info.db_page_size);
        }
+       return 0;
 }
 
 static int ocrdma_add_qpn_map(struct ocrdma_dev *dev, struct ocrdma_qp *qp)
index 4f6806f16e61c563898ca5b16881df65c72af7b5..425d554e7f3f5fcb0b4f3340c183b7266bc9b463 100644 (file)
@@ -72,7 +72,7 @@ int ocrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
 int ocrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                     struct ib_udata *udata);
 int ocrdma_resize_cq(struct ib_cq *, int cqe, struct ib_udata *);
-void ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
+int ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
 
 struct ib_qp *ocrdma_create_qp(struct ib_pd *,
                               struct ib_qp_init_attr *attrs,
index 7d65824f77bc067cda887b71bda2e5af1d3d5c3e..02368c3df80267cf506c991280f1c7e9ddf34cb0 100644 (file)
@@ -1052,7 +1052,7 @@ int qedr_resize_cq(struct ib_cq *ibcq, int new_cnt, struct ib_udata *udata)
 #define QEDR_DESTROY_CQ_MAX_ITERATIONS         (10)
 #define QEDR_DESTROY_CQ_ITER_DURATION          (10)
 
-void qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+int qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct qedr_dev *dev = get_qedr_dev(ibcq->device);
        struct qed_rdma_destroy_cq_out_params oparams;
@@ -1067,7 +1067,7 @@ void qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
        /* GSIs CQs are handled by driver, so they don't exist in the FW */
        if (cq->cq_type == QEDR_CQ_TYPE_GSI) {
                qedr_db_recovery_del(dev, cq->db_addr, &cq->db.data);
-               return;
+               return 0;
        }
 
        iparams.icid = cq->icid;
@@ -1115,6 +1115,7 @@ void qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
         * Since the destroy CQ ramrod has also been received on the EQ we can
         * be certain that there's no event handler in process.
         */
+       return 0;
 }
 
 static inline int get_gid_info_from_table(struct ib_qp *ibqp,
index a78b206d8b5afae35441b8d12cb7f2a32b3ec5ba..4620fba34d5f90f0406705b78171b146b6d6a31f 100644 (file)
@@ -52,7 +52,7 @@ int qedr_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
 int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                   struct ib_udata *udata);
 int qedr_resize_cq(struct ib_cq *, int cqe, struct ib_udata *);
-void qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
+int qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
 int qedr_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
 struct ib_qp *qedr_create_qp(struct ib_pd *, struct ib_qp_init_attr *attrs,
                             struct ib_udata *);
index 8af3212101be4b7b2c9e762d456be0623eaa54db..9e961f8ffa10dee25902a32ab107c7b889ee94a8 100644 (file)
@@ -586,9 +586,9 @@ int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
        return 0;
 }
 
-void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
+int usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 {
-       return;
+       return 0;
 }
 
 struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
index f8911c0330e29454fd48c94b80dcb2889190ba1c..11fe1ba6bbc9a53363c055db7f239bc9e33714bd 100644 (file)
@@ -58,7 +58,7 @@ int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                                int attr_mask, struct ib_udata *udata);
 int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                       struct ib_udata *udata);
-void usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
+int usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
 struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
                                u64 virt_addr, int access_flags,
                                struct ib_udata *udata);
index 01cd122a8b692fa5fa55fb0e1e5c930d371b3043..32aede5a3381a8db494775856a33389c68677aa2 100644 (file)
@@ -235,7 +235,7 @@ static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq)
  * @cq: the completion queue to destroy.
  * @udata: user data or null for kernel object
  */
-void pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
+int pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 {
        struct pvrdma_cq *vcq = to_vcq(cq);
        union pvrdma_cmd_req req;
@@ -261,6 +261,7 @@ void pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
 
        pvrdma_free_cq(dev, vcq);
        atomic_dec(&dev->num_cqs);
+       return 0;
 }
 
 static inline struct pvrdma_cqe *get_cqe(struct pvrdma_cq *cq, int i)
index f9edce71b79bb40f9d6312c5698b2eebb6413ee2..97ed8f952f6e94c750083333f4f17dfc03e764a0 100644 (file)
@@ -411,7 +411,7 @@ int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
                     int sg_nents, unsigned int *sg_offset);
 int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                     struct ib_udata *udata);
-void pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
+int pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
 int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
 int pvrdma_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
index 04d2e72017fedaefe23ddb25900f583240cac8ca..19248be140933592c3ebe53ecb2ef87a47e9bd56 100644 (file)
@@ -315,7 +315,7 @@ bail_wc:
  *
  * Called by ib_destroy_cq() in the generic verbs code.
  */
-void rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+int rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct rvt_cq *cq = ibcq_to_rvtcq(ibcq);
        struct rvt_dev_info *rdi = cq->rdi;
@@ -328,6 +328,7 @@ void rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
                kref_put(&cq->ip->ref, rvt_release_mmap_info);
        else
                vfree(cq->kqueue);
+       return 0;
 }
 
 /**
index 5e26a2eb19a4c6d1e31f1b4d1e1cc1dd5bbbf44c..feb01e7ee00449e72b72f1aab06c8ecdb052f537 100644 (file)
@@ -53,7 +53,7 @@
 
 int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                  struct ib_udata *udata);
-void rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
+int rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
 int rvt_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags);
 int rvt_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
 int rvt_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry);
index df5e9b0157eff057dba640c97e3b70d55061aa61..5a4087b0175784570224a781c6396601adcf2b96 100644 (file)
@@ -779,13 +779,14 @@ static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
        return rxe_add_to_pool(&rxe->cq_pool, &cq->pelem);
 }
 
-static void rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
+static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct rxe_cq *cq = to_rcq(ibcq);
 
        rxe_cq_disable(cq);
 
        rxe_drop_ref(cq);
+       return 0;
 }
 
 static int rxe_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata)
index a6ec1e968fb41e6927e37a56025f8f42a6d396d8..7cf3242ffb41f9b8438395c30ea16ca9be8479c5 100644 (file)
@@ -1056,7 +1056,7 @@ int siw_post_receive(struct ib_qp *base_qp, const struct ib_recv_wr *wr,
        return rv > 0 ? 0 : rv;
 }
 
-void siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata)
+int siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata)
 {
        struct siw_cq *cq = to_siw_cq(base_cq);
        struct siw_device *sdev = to_siw_dev(base_cq->device);
@@ -1074,6 +1074,7 @@ void siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata)
        atomic_dec(&sdev->num_cq);
 
        vfree(cq->queue);
+       return 0;
 }
 
 /*
index ed2d8ac2f967bcbe1d71576e83b16be04bfba6df..63745452935753ae44bac96f1a5c80713bb49de2 100644 (file)
@@ -62,7 +62,7 @@ int siw_post_send(struct ib_qp *base_qp, const struct ib_send_wr *wr,
                  const struct ib_send_wr **bad_wr);
 int siw_post_receive(struct ib_qp *base_qp, const struct ib_recv_wr *wr,
                     const struct ib_recv_wr **bad_wr);
-void siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata);
+int siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata);
 int siw_poll_cq(struct ib_cq *base_cq, int num_entries, struct ib_wc *wc);
 int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags);
 struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd, u64 start, u64 len,
index b74fd1a5ccb6fff5f3c125cdb1d56f4ed7e60b5d..bec05baaeaedfe03154cdc53ce5a57744216a6fa 100644 (file)
@@ -2423,7 +2423,7 @@ struct ib_device_ops {
        int (*create_cq)(struct ib_cq *cq, const struct ib_cq_init_attr *attr,
                         struct ib_udata *udata);
        int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
-       void (*destroy_cq)(struct ib_cq *cq, struct ib_udata *udata);
+       int (*destroy_cq)(struct ib_cq *cq, struct ib_udata *udata);
        int (*resize_cq)(struct ib_cq *cq, int cqe, struct ib_udata *udata);
        struct ib_mr *(*get_dma_mr)(struct ib_pd *pd, int mr_access_flags);
        struct ib_mr *(*reg_user_mr)(struct ib_pd *pd, u64 start, u64 length,
@@ -3890,7 +3890,9 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata);
  */
 static inline void ib_destroy_cq(struct ib_cq *cq)
 {
-       ib_destroy_cq_user(cq, NULL);
+       int ret = ib_destroy_cq_user(cq, NULL);
+
+       WARN_ONCE(ret, "Destroy of kernel CQ shouldn't fail");
 }
 
 /**