RDMA: Restore ability to fail on PD deallocate
authorLeon Romanovsky <leonro@mellanox.com>
Mon, 7 Sep 2020 12:09:13 +0000 (15:09 +0300)
committerJason Gunthorpe <jgg@nvidia.com>
Wed, 9 Sep 2020 16:57:22 +0000 (13:57 -0300)
The IB verbs objects are counted by the kernel and ib_core ensures that
deallocate PD will success so it will be called once all other objects
that depends on PD will be released. This is achieved by managing various
reference counters on such objects.

The mlx5 driver didn't follow this standard flow when allowed DEVX objects
that are not managed by ib_core to be interleaved with the ones under
ib_core responsibility.

In such interleaved scenarios deallocate command can fail and ib_core will
leave uobject in internal DB and attempt to clean it later to free
resources anyway.

This change partially restores returned value from dealloc_pd() for all
drivers, but keeping in mind that non-DEVX devices and kernel verbs paths
shouldn't fail.

Fixes: 21a428a019c9 ("RDMA: Handle PD allocations by IB/core")
Link: https://lore.kernel.org/r/20200907120921.476363-2-leon@kernel.org
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
29 files changed:
drivers/infiniband/core/uverbs_std_types.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/provider.c
drivers/infiniband/hw/efa/efa.h
drivers/infiniband/hw/efa/efa_verbs.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_pd.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/cmd.c
drivers/infiniband/hw/mlx5/cmd.h
drivers/infiniband/hw/mlx5/main.c
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_verbs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h
drivers/infiniband/sw/rdmavt/pd.c
drivers/infiniband/sw/rdmavt/pd.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 08c39cfb1bd9bed5c0a9080398df0fff9a0d739a..2932e832f48fc4ddf2da91d9c816ac7dc466b5f5 100644 (file)
@@ -122,8 +122,7 @@ static int uverbs_free_pd(struct ib_uobject *uobject,
        if (ret)
                return ret;
 
-       ib_dealloc_pd_user(pd, &attrs->driver_udata);
-       return 0;
+       return ib_dealloc_pd_user(pd, &attrs->driver_udata);
 }
 
 void ib_uverbs_free_event_queue(struct ib_uverbs_event_queue *event_queue)
index 3096e73797b775f706c4d257fd140024c9031ebe..a4a2cd378cb497ab3217220729258fc3e6247b01 100644 (file)
@@ -329,7 +329,7 @@ EXPORT_SYMBOL(__ib_alloc_pd);
  * exist.  The caller is responsible to synchronously destroy them and
  * guarantee no new allocations will happen.
  */
-void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
+int ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
 {
        int ret;
 
@@ -343,9 +343,13 @@ void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
           requires the caller to guarantee we can't race here. */
        WARN_ON(atomic_read(&pd->usecnt));
 
+       ret = pd->device->ops.dealloc_pd(pd, udata);
+       if (ret)
+               return ret;
+
        rdma_restrack_del(&pd->res);
-       pd->device->ops.dealloc_pd(pd, udata);
        kfree(pd);
+       return ret;
 }
 EXPORT_SYMBOL(ib_dealloc_pd_user);
 
index 5ee272d27aaadea1bde1900afcf5878403da150b..c53f6e329d84deac3df5c5fb3471e3a8afbda723 100644 (file)
@@ -532,7 +532,7 @@ fail:
 }
 
 /* Protection Domains */
-void bnxt_re_dealloc_pd(struct ib_pd *ib_pd, struct ib_udata *udata)
+int bnxt_re_dealloc_pd(struct ib_pd *ib_pd, struct ib_udata *udata)
 {
        struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
        struct bnxt_re_dev *rdev = pd->rdev;
@@ -542,6 +542,7 @@ void bnxt_re_dealloc_pd(struct ib_pd *ib_pd, struct ib_udata *udata)
        if (pd->qplib_pd.id)
                bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl,
                                      &pd->qplib_pd);
+       return 0;
 }
 
 int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
index 1daeb30e06fda31d4bad167d44fbc328b2c5a4f9..d9e2e406f66addbf1539c810bbc35ddd997394a0 100644 (file)
@@ -163,7 +163,7 @@ int bnxt_re_query_gid(struct ib_device *ibdev, u8 port_num,
 enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
                                            u8 port_num);
 int bnxt_re_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void bnxt_re_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
+int bnxt_re_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
 int bnxt_re_create_ah(struct ib_ah *ah, struct rdma_ah_init_attr *init_attr,
                      struct ib_udata *udata);
 int bnxt_re_modify_ah(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
index 6c579d2d399749e5c9fbaf2bc532903ebd4c2da8..5f2b30624512494623a3f9de329343b95c3f77c0 100644 (file)
@@ -190,7 +190,7 @@ static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        return ret;
 }
 
-static void c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
+static int c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        struct c4iw_dev *rhp;
        struct c4iw_pd *php;
@@ -202,6 +202,7 @@ static void c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
        mutex_lock(&rhp->rdev.stats.lock);
        rhp->rdev.stats.pd.cur--;
        mutex_unlock(&rhp->rdev.stats.lock);
+       return 0;
 }
 
 static int c4iw_allocate_pd(struct ib_pd *pd, struct ib_udata *udata)
index 1889dd172a252749e03dece0e1572fdf6b4c67b2..8547f9d543dfb914550be59bd8649d340057b47a 100644 (file)
@@ -134,7 +134,7 @@ int efa_query_gid(struct ib_device *ibdev, u8 port, int index,
 int efa_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
                   u16 *pkey);
 int efa_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
-void efa_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
+int efa_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
 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,
index de9a22f0fcc218f054f0f6fd8c591a0dbd923538..383ce126d82f3c95de0fd061d4aaaf070cf4e428 100644 (file)
@@ -383,13 +383,14 @@ err_out:
        return err;
 }
 
-void efa_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+int efa_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct efa_dev *dev = to_edev(ibpd->device);
        struct efa_pd *pd = to_epd(ibpd);
 
        ibdev_dbg(&dev->ibdev, "Dealloc pd[%d]\n", pd->pdn);
        efa_pd_dealloc(dev, pd->pdn);
+       return 0;
 }
 
 static int efa_destroy_qp_handle(struct efa_dev *dev, u32 qp_handle)
index 4f1dd916d05ff7fd403178471ab45d49c744d9df..9688240d7fce2a68d227e4c39f78ee41d8c85589 100644 (file)
@@ -1182,7 +1182,7 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
 void hns_roce_destroy_ah(struct ib_ah *ah, u32 flags);
 
 int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
+int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
 
 struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc);
 struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
index b10c50b8736eccccc06e6b916a7c790ecdaeee1e..98f69496adb495f7454fc496937ef1539b77f189 100644 (file)
@@ -82,9 +82,10 @@ int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        hns_roce_pd_free(to_hr_dev(pd->device), to_hr_pd(pd)->pdn);
+       return 0;
 }
 
 int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
index b51339328a51eff1f153362f4479c29c301309e9..c0f796cb6e5e303b2535e41d816c8d5f7b448614 100644 (file)
@@ -328,12 +328,13 @@ error:
  * @ibpd: ptr of pd to be deallocated
  * @udata: user data or null for kernel object
  */
-static void i40iw_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+static int i40iw_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct i40iw_pd *iwpd = to_iwpd(ibpd);
        struct i40iw_device *iwdev = to_iwdev(ibpd->device);
 
        i40iw_rem_pdusecount(iwpd, iwdev);
+       return 0;
 }
 
 /**
index 2543062c0cb05553df0fcdeea169681e8d57743f..1be0108db992690f2ac05c3b095e8f65b1ba5f36 100644 (file)
@@ -1214,9 +1214,10 @@ static int mlx4_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-static void mlx4_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+static int mlx4_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        mlx4_pd_free(to_mdev(pd->device)->dev, to_mpd(pd)->pdn);
+       return 0;
 }
 
 static int mlx4_ib_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
index ebb2f108b64f14fd79eb8caa0bb7a456858f73e3..f5aac53cebf04e59200190aaacc54d02b5c9be32 100644 (file)
@@ -209,14 +209,14 @@ void mlx5_cmd_dealloc_transport_domain(struct mlx5_core_dev *dev, u32 tdn,
        mlx5_cmd_exec_in(dev, dealloc_transport_domain, in);
 }
 
-void mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid)
+int mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid)
 {
        u32 in[MLX5_ST_SZ_DW(dealloc_pd_in)] = {};
 
        MLX5_SET(dealloc_pd_in, in, opcode, MLX5_CMD_OP_DEALLOC_PD);
        MLX5_SET(dealloc_pd_in, in, pd, pdn);
        MLX5_SET(dealloc_pd_in, in, uid, uid);
-       mlx5_cmd_exec_in(dev, dealloc_pd, in);
+       return mlx5_cmd_exec_in(dev, dealloc_pd, in);
 }
 
 int mlx5_cmd_attach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
index 1d192a8ca87dc7f7024dd489129590f82cb9786e..ca3afa7d73a3f8f77fc700cba40f38c8460990d1 100644 (file)
@@ -44,7 +44,7 @@ int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
 int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
                         u64 length, u32 alignment);
 void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
-void mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid);
+int mlx5_cmd_dealloc_pd(struct mlx5_core_dev *dev, u32 pdn, u16 uid);
 void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid);
 void mlx5_cmd_destroy_tis(struct mlx5_core_dev *dev, u32 tisn, u16 uid);
 void mlx5_cmd_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn, u16 uid);
index d60d63221b14d9224535f9d8dac42d1d5d7c288a..bfa8b6b3c68134a6ae7a6d74f8d000da37298c98 100644 (file)
@@ -2569,12 +2569,12 @@ static int mlx5_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-static void mlx5_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+static int mlx5_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        struct mlx5_ib_dev *mdev = to_mdev(pd->device);
        struct mlx5_ib_pd *mpd = to_mpd(pd);
 
-       mlx5_cmd_dealloc_pd(mdev->mdev, mpd->pdn, mpd->uid);
+       return mlx5_cmd_dealloc_pd(mdev->mdev, mpd->pdn, mpd->uid);
 }
 
 static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
index 9fa2f9164a47b62dbe89ffaf2fd01e9c475802e6..d3ed7c19b2ef410502baecbb5cab48b72530d819 100644 (file)
@@ -373,9 +373,10 @@ static int mthca_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-static void mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+static int mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
+       return 0;
 }
 
 static int mthca_ah_create(struct ib_ah *ibah,
index c1751c9a0f625c92b97f60010417f3c8857b7172..a9d2f7a40b5153ee1e57276faeb614ee83a56ec7 100644 (file)
@@ -664,7 +664,7 @@ exit:
        return status;
 }
 
-void ocrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+int ocrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
        struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
@@ -682,10 +682,11 @@ void ocrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 
                if (is_ucontext_pd(uctx, pd)) {
                        ocrdma_release_ucontext_pd(uctx);
-                       return;
+                       return 0;
                }
        }
        _ocrdma_dealloc_pd(dev, pd);
+       return 0;
 }
 
 static int ocrdma_alloc_lkey(struct ocrdma_dev *dev, struct ocrdma_mr *mr,
index df8e3b923a440c9e7bd4c5008c028851ccd2fb6c..4c85be43507cf5eb1b9cdeca6a3ee66f7baa3b46 100644 (file)
@@ -67,7 +67,7 @@ void ocrdma_dealloc_ucontext(struct ib_ucontext *uctx);
 int ocrdma_mmap(struct ib_ucontext *, struct vm_area_struct *vma);
 
 int ocrdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void ocrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
+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);
index 0bdfa300865d572f3544c402a6fc407e53cf567c..c81d1e5472957e115b6f523ea5fc193ccc312807 100644 (file)
@@ -471,13 +471,14 @@ int qedr_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-void qedr_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+int qedr_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct qedr_dev *dev = get_qedr_dev(ibpd->device);
        struct qedr_pd *pd = get_qedr_pd(ibpd);
 
        DP_DEBUG(dev, QEDR_MSG_INIT, "Deallocating PD %d\n", pd->pd_id);
        dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd->pd_id);
+       return 0;
 }
 
 static void qedr_free_pbl(struct qedr_dev *dev,
index 39dd6286ba39558f4af567640894f675fb195619..1b450919ba9ca589dd7518477ef4002fb2e6a186 100644 (file)
@@ -47,7 +47,7 @@ void qedr_dealloc_ucontext(struct ib_ucontext *uctx);
 int qedr_mmap(struct ib_ucontext *ucontext, struct vm_area_struct *vma);
 void qedr_mmap_free(struct rdma_user_mmap_entry *rdma_entry);
 int qedr_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void qedr_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
+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);
index 02a49f661c8d4cc2b770c7ea7b1413e51f8f0f8b..8af3212101be4b7b2c9e762d456be0623eaa54db 100644 (file)
@@ -449,9 +449,10 @@ int usnic_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return 0;
 }
 
-void usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+int usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        usnic_uiom_dealloc_pd((to_upd(pd))->umem_pd);
+       return 0;
 }
 
 struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
index 9195f2b901ce37442131483b880e7432b5099f86..f8911c0330e29454fd48c94b80dcb2889190ba1c 100644 (file)
@@ -49,7 +49,7 @@ int usnic_ib_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
 int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
                                union ib_gid *gid);
 int usnic_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
-void usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
+int usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
 struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
                                        struct ib_qp_init_attr *init_attr,
                                        struct ib_udata *udata);
index 65ac3693ad120b1b8f88bcdf4f3877fb2d92ba57..678c94531e6843c3a1a4ee702bb87f540fa86ab5 100644 (file)
@@ -479,9 +479,9 @@ err:
  * @pd: the protection domain to be released
  * @udata: user data or null for kernel object
  *
- * @return: 0 on success, otherwise errno.
+ * @return: Always 0
  */
-void pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+int pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        struct pvrdma_dev *dev = to_vdev(pd->device);
        union pvrdma_cmd_req req = {};
@@ -498,6 +498,7 @@ void pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
                         ret);
 
        atomic_dec(&dev->num_pds);
+       return 0;
 }
 
 /**
index 699b20849a7efa0026efbf59e6b51b15cc232b87..7bf33a65427589d1c545236b5a2c0fa76665815a 100644 (file)
@@ -399,7 +399,7 @@ int pvrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 int pvrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata);
 void pvrdma_dealloc_ucontext(struct ib_ucontext *context);
 int pvrdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void pvrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
+int pvrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
 struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc);
 struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                 u64 virt_addr, int access_flags,
index a403718f0b5ec7c597007879b2ca6f3489b2b5a3..01b7abf9152054760950e18e154839151a329e27 100644 (file)
@@ -95,11 +95,12 @@ bail:
  *
  * Return: always 0
  */
-void rvt_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+int rvt_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct rvt_dev_info *dev = ib_to_rvt(ibpd->device);
 
        spin_lock(&dev->n_pds_lock);
        dev->n_pds_allocated--;
        spin_unlock(&dev->n_pds_lock);
+       return 0;
 }
index 71ba76d72b1d895d09022b5ac2704252d2d3a6ea..06a6a38beedc8f0417e6f39afb1b26c2f598e851 100644 (file)
@@ -51,6 +51,6 @@
 #include <rdma/rdma_vt.h>
 
 int rvt_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
-void rvt_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
+int rvt_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata);
 
 #endif          /* DEF_RDMAVTPD_H */
index 36edc294e105f96709495a1cf2c60d9eec1a54cd..7fe7316bd2874ddd2400f90ece5c006191ae729b 100644 (file)
@@ -148,11 +148,12 @@ static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
        return rxe_add_to_pool(&rxe->pd_pool, &pd->pelem);
 }
 
-static void rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
+static int rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct rxe_pd *pd = to_rpd(ibpd);
 
        rxe_drop_ref(pd);
+       return 0;
 }
 
 static int rxe_create_ah(struct ib_ah *ibah,
index adafa1b8bebe389db9012fc355ee6e27c3874c68..2d2b6df0b027cb898170445743071eef16d26d7d 100644 (file)
@@ -234,12 +234,13 @@ int siw_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
        return 0;
 }
 
-void siw_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+int siw_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
        struct siw_device *sdev = to_siw_dev(pd->device);
 
        siw_dbg_pd(pd, "free PD\n");
        atomic_dec(&sdev->num_pd);
+       return 0;
 }
 
 void siw_qp_get_ref(struct ib_qp *base_qp)
index d9572275a6b69557c7add81e331657f9238d0051..3dbab78579cb3dd242ed6d088507e5011775e7d9 100644 (file)
@@ -49,7 +49,7 @@ int siw_query_port(struct ib_device *base_dev, u8 port,
 int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,
                  union ib_gid *gid);
 int siw_alloc_pd(struct ib_pd *base_pd, struct ib_udata *udata);
-void siw_dealloc_pd(struct ib_pd *base_pd, struct ib_udata *udata);
+int siw_dealloc_pd(struct ib_pd *base_pd, struct ib_udata *udata);
 struct ib_qp *siw_create_qp(struct ib_pd *base_pd,
                            struct ib_qp_init_attr *attr,
                            struct ib_udata *udata);
index 3781d36df31c0e0b2650435736db05c6aa93b092..a49aaebaed58545e85a5e78d4471127094408b2c 100644 (file)
@@ -2398,7 +2398,7 @@ struct ib_device_ops {
        void (*mmap_free)(struct rdma_user_mmap_entry *entry);
        void (*disassociate_ucontext)(struct ib_ucontext *ibcontext);
        int (*alloc_pd)(struct ib_pd *pd, struct ib_udata *udata);
-       void (*dealloc_pd)(struct ib_pd *pd, struct ib_udata *udata);
+       int (*dealloc_pd)(struct ib_pd *pd, struct ib_udata *udata);
        int (*create_ah)(struct ib_ah *ah, struct rdma_ah_init_attr *attr,
                         struct ib_udata *udata);
        int (*modify_ah)(struct ib_ah *ah, struct rdma_ah_attr *ah_attr);
@@ -3456,12 +3456,7 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
 #define ib_alloc_pd(device, flags) \
        __ib_alloc_pd((device), (flags), KBUILD_MODNAME)
 
-/**
- * ib_dealloc_pd_user - Deallocate kernel/user PD
- * @pd: The protection domain
- * @udata: Valid user data or NULL for kernel objects
- */
-void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata);
+int ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata);
 
 /**
  * ib_dealloc_pd - Deallocate kernel PD
@@ -3471,7 +3466,9 @@ void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata);
  */
 static inline void ib_dealloc_pd(struct ib_pd *pd)
 {
-       ib_dealloc_pd_user(pd, NULL);
+       int ret = ib_dealloc_pd_user(pd, NULL);
+
+       WARN_ONCE(ret, "Destroy of kernel PD shouldn't fail");
 }
 
 enum rdma_create_ah_flags {