]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA: Handle PD allocations by IB/core
authorLeon Romanovsky <leonro@mellanox.com>
Sun, 3 Feb 2019 12:55:51 +0000 (14:55 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 8 Feb 2019 23:51:04 +0000 (16:51 -0700)
The PD allocations in IB/core allows us to simplify drivers and their
error flows in their .alloc_pd() paths. The changes in .alloc_pd() go hand
in had with relevant update in .dealloc_pd().

We will use this opportunity and convert .dealloc_pd() to don't fail, as
it was suggested a long time ago, failures are not happening as we have
never seen a WARN_ON print.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
39 files changed:
drivers/infiniband/core/device.c
drivers/infiniband/core/uverbs_cmd.c
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/bnxt_re/main.c
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/infiniband/hw/cxgb4/provider.c
drivers/infiniband/hw/hns/hns_roce_device.h
drivers/infiniband/hw/hns/hns_roce_hw_v1.c
drivers/infiniband/hw/hns/hns_roce_main.c
drivers/infiniband/hw/hns/hns_roce_pd.c
drivers/infiniband/hw/i40iw/i40iw_utils.c
drivers/infiniband/hw/i40iw/i40iw_verbs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mthca/mthca_provider.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_main.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
drivers/infiniband/hw/ocrdma/ocrdma_verbs.h
drivers/infiniband/hw/qedr/main.c
drivers/infiniband/hw/qedr/verbs.c
drivers/infiniband/hw/qedr/verbs.h
drivers/infiniband/hw/usnic/usnic_ib_main.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.c
drivers/infiniband/hw/usnic/usnic_ib_verbs.h
drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
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/rdmavt/vt.c
drivers/infiniband/sw/rxe/rxe_pool.c
drivers/infiniband/sw/rxe/rxe_pool.h
drivers/infiniband/sw/rxe/rxe_verbs.c
drivers/infiniband/sw/rxe/rxe_verbs.h
include/rdma/ib_verbs.h

index d806a5c7b2024d0263ffcfc47109f7b1fe1627fa..57e1e177921ef04833c318406b2141efc50ffc49 100644 (file)
@@ -1319,6 +1319,8 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
        SET_DEVICE_OP(dev_ops, set_vf_guid);
        SET_DEVICE_OP(dev_ops, set_vf_link_state);
        SET_DEVICE_OP(dev_ops, unmap_fmr);
+
+       SET_OBJ_SIZE(dev_ops, ib_pd);
 }
 EXPORT_SYMBOL(ib_set_device_ops);
 
index aa260cafbd85a412db77fb42babb0e6716561f33..5ac143f22df00912659ecfc84678496fa10d7a8f 100644 (file)
@@ -407,9 +407,9 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
-       pd = ib_dev->ops.alloc_pd(ib_dev, uobj->context, &attrs->driver_udata);
-       if (IS_ERR(pd)) {
-               ret = PTR_ERR(pd);
+       pd = rdma_zalloc_drv_obj(ib_dev, ib_pd);
+       if (!pd) {
+               ret = -ENOMEM;
                goto err;
        }
 
@@ -417,11 +417,15 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
        pd->uobject = uobj;
        pd->__internal_mr = NULL;
        atomic_set(&pd->usecnt, 0);
+       pd->res.type = RDMA_RESTRACK_PD;
+
+       ret = ib_dev->ops.alloc_pd(pd, uobj->context, &attrs->driver_udata);
+       if (ret)
+               goto err_alloc;
 
        uobj->object = pd;
        memset(&resp, 0, sizeof resp);
        resp.pd_handle = uobj->id;
-       pd->res.type = RDMA_RESTRACK_PD;
        rdma_restrack_uadd(&pd->res);
 
        ret = uverbs_response(attrs, &resp, sizeof(resp));
@@ -432,7 +436,8 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
 
 err_copy:
        ib_dealloc_pd(pd);
-
+err_alloc:
+       kfree(pd);
 err:
        uobj_alloc_abort(uobj);
        return ret;
index cbc72312eb41d26f33540f58e9ff3845f90873f5..f224cb7272249bdd313d01016bfead6c698860c1 100644 (file)
@@ -188,7 +188,7 @@ static int uverbs_free_pd(struct ib_uobject *uobject,
        if (ret)
                return ret;
 
-       ib_dealloc_pd((struct ib_pd *)uobject->object);
+       ib_dealloc_pd(pd);
        return 0;
 }
 
index 3220fb42eccec96a3da559070ec9c7b39c065d1d..de5d895a50544ceeab721331e15a3e04d46d21e4 100644 (file)
@@ -254,10 +254,11 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
 {
        struct ib_pd *pd;
        int mr_access_flags = 0;
+       int ret;
 
-       pd = device->ops.alloc_pd(device, NULL, NULL);
-       if (IS_ERR(pd))
-               return pd;
+       pd = rdma_zalloc_drv_obj(device, ib_pd);
+       if (!pd)
+               return ERR_PTR(-ENOMEM);
 
        pd->device = device;
        pd->uobject = NULL;
@@ -265,6 +266,16 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
        atomic_set(&pd->usecnt, 0);
        pd->flags = flags;
 
+       pd->res.type = RDMA_RESTRACK_PD;
+       rdma_restrack_set_task(&pd->res, caller);
+
+       ret = device->ops.alloc_pd(pd, NULL, NULL);
+       if (ret) {
+               kfree(pd);
+               return ERR_PTR(ret);
+       }
+       rdma_restrack_kadd(&pd->res);
+
        if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
                pd->local_dma_lkey = device->local_dma_lkey;
        else
@@ -275,10 +286,6 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
                mr_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE;
        }
 
-       pd->res.type = RDMA_RESTRACK_PD;
-       rdma_restrack_set_task(&pd->res, caller);
-       rdma_restrack_kadd(&pd->res);
-
        if (mr_access_flags) {
                struct ib_mr *mr;
 
@@ -329,10 +336,8 @@ void ib_dealloc_pd(struct ib_pd *pd)
        WARN_ON(atomic_read(&pd->usecnt));
 
        rdma_restrack_del(&pd->res);
-       /* Making delalloc_pd a void return is a WIP, no driver should return
-          an error here. */
-       ret = pd->device->ops.dealloc_pd(pd);
-       WARN_ONCE(ret, "Infiniband HW driver failed dealloc_pd");
+       pd->device->ops.dealloc_pd(pd);
+       kfree(pd);
 }
 EXPORT_SYMBOL(ib_dealloc_pd);
 
index 1d7469e23cde0a06a0618f13099fa68b30e6dab0..1606571af63d6be1e53e31168742ba6902db0849 100644 (file)
@@ -563,41 +563,29 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
 }
 
 /* Protection Domains */
-int bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
+void bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
 {
        struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
        struct bnxt_re_dev *rdev = pd->rdev;
-       int rc;
 
        bnxt_re_destroy_fence_mr(pd);
 
-       if (pd->qplib_pd.id) {
-               rc = bnxt_qplib_dealloc_pd(&rdev->qplib_res,
-                                          &rdev->qplib_res.pd_tbl,
-                                          &pd->qplib_pd);
-               if (rc)
-                       dev_err(rdev_to_dev(rdev), "Failed to deallocate HW PD");
-       }
-
-       kfree(pd);
-       return 0;
+       if (pd->qplib_pd.id)
+               bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl,
+                                     &pd->qplib_pd);
 }
 
-struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
-                              struct ib_ucontext *ucontext,
-                              struct ib_udata *udata)
+int bnxt_re_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *ucontext,
+                    struct ib_udata *udata)
 {
+       struct ib_device *ibdev = ibpd->device;
        struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
        struct bnxt_re_ucontext *ucntx = container_of(ucontext,
                                                      struct bnxt_re_ucontext,
                                                      ib_uctx);
-       struct bnxt_re_pd *pd;
+       struct bnxt_re_pd *pd = container_of(ibpd, struct bnxt_re_pd, ib_pd);
        int rc;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        pd->rdev = rdev;
        if (bnxt_qplib_alloc_pd(&rdev->qplib_res.pd_tbl, &pd->qplib_pd)) {
                dev_err(rdev_to_dev(rdev), "Failed to allocate HW PD");
@@ -637,13 +625,12 @@ struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
                if (bnxt_re_create_fence_mr(pd))
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to create Fence-MR\n");
-       return &pd->ib_pd;
+       return 0;
 dbfail:
-       (void)bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl,
-                                   &pd->qplib_pd);
+       bnxt_qplib_dealloc_pd(&rdev->qplib_res, &rdev->qplib_res.pd_tbl,
+                             &pd->qplib_pd);
 fail:
-       kfree(pd);
-       return ERR_PTR(rc);
+       return rc;
 }
 
 /* Address Handles */
index c4af72604b4feef5a772a0190681932a41b914f8..c7cca803cfa3fe266a7932541a87e56e30361b0b 100644 (file)
@@ -56,8 +56,8 @@ struct bnxt_re_fence_data {
 };
 
 struct bnxt_re_pd {
+       struct ib_pd            ib_pd;
        struct bnxt_re_dev      *rdev;
-       struct ib_pd            ib_pd;
        struct bnxt_qplib_pd    qplib_pd;
        struct bnxt_re_fence_data fence;
 };
@@ -163,10 +163,9 @@ int bnxt_re_query_gid(struct ib_device *ibdev, u8 port_num,
                      int index, union ib_gid *gid);
 enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
                                            u8 port_num);
-struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
-                              struct ib_ucontext *context,
-                              struct ib_udata *udata);
-int bnxt_re_dealloc_pd(struct ib_pd *pd);
+int bnxt_re_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                    struct ib_udata *udata);
+void bnxt_re_dealloc_pd(struct ib_pd *pd);
 struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd,
                                struct rdma_ah_attr *ah_attr,
                                u32 flags,
index 0d40a930c1922d486a027564caf20dca7ef1e194..0a89ef6e57541d598d985ea183bec0237d723ec8 100644 (file)
@@ -637,6 +637,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = {
        .query_srq = bnxt_re_query_srq,
        .reg_user_mr = bnxt_re_reg_user_mr,
        .req_notify_cq = bnxt_re_req_notify_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd),
 };
 
 static int bnxt_re_register_ib(struct bnxt_re_dev *rdev)
index 804c1fc7bfc129881d0c49b1a04b96674b728ca5..4cc9a6ae21396af3443838bf145ad093f51fc80c 100644 (file)
@@ -370,7 +370,7 @@ static int iwch_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        return ret;
 }
 
-static int iwch_deallocate_pd(struct ib_pd *pd)
+static void iwch_deallocate_pd(struct ib_pd *pd)
 {
        struct iwch_dev *rhp;
        struct iwch_pd *php;
@@ -379,15 +379,13 @@ static int iwch_deallocate_pd(struct ib_pd *pd)
        rhp = php->rhp;
        pr_debug("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid);
        cxio_hal_put_pdid(rhp->rdev.rscp, php->pdid);
-       kfree(php);
-       return 0;
 }
 
-static struct ib_pd *iwch_allocate_pd(struct ib_device *ibdev,
-                              struct ib_ucontext *context,
-                              struct ib_udata *udata)
+static int iwch_allocate_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                           struct ib_udata *udata)
 {
-       struct iwch_pd *php;
+       struct iwch_pd *php = to_iwch_pd(pd);
+       struct ib_device *ibdev = pd->device;
        u32 pdid;
        struct iwch_dev *rhp;
 
@@ -395,12 +393,8 @@ static struct ib_pd *iwch_allocate_pd(struct ib_device *ibdev,
        rhp = (struct iwch_dev *) ibdev;
        pdid = cxio_hal_get_pdid(rhp->rdev.rscp);
        if (!pdid)
-               return ERR_PTR(-EINVAL);
-       php = kzalloc(sizeof(*php), GFP_KERNEL);
-       if (!php) {
-               cxio_hal_put_pdid(rhp->rdev.rscp, pdid);
-               return ERR_PTR(-ENOMEM);
-       }
+               return -EINVAL;
+
        php->pdid = pdid;
        php->rhp = rhp;
        if (context) {
@@ -408,11 +402,11 @@ static struct ib_pd *iwch_allocate_pd(struct ib_device *ibdev,
 
                if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
                        iwch_deallocate_pd(&php->ibpd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
        pr_debug("%s pdid 0x%0x ptr 0x%p\n", __func__, pdid, php);
-       return &php->ibpd;
+       return 0;
 }
 
 static int iwch_dereg_mr(struct ib_mr *ib_mr)
@@ -1350,6 +1344,7 @@ static const struct ib_device_ops iwch_dev_ops = {
        .reg_user_mr = iwch_reg_user_mr,
        .req_notify_cq = iwch_arm_cq,
        .resize_cq = iwch_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, iwch_pd, ibpd),
 };
 
 int iwch_register_device(struct iwch_dev *dev)
index f59bf7e5a5891a23748f61fc682bf17dd8dcc1ad..680b5e98491d3eb59c4030b2376910503ec811f5 100644 (file)
@@ -209,7 +209,7 @@ static int c4iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        return ret;
 }
 
-static int c4iw_deallocate_pd(struct ib_pd *pd)
+static void c4iw_deallocate_pd(struct ib_pd *pd)
 {
        struct c4iw_dev *rhp;
        struct c4iw_pd *php;
@@ -221,15 +221,13 @@ static int c4iw_deallocate_pd(struct ib_pd *pd)
        mutex_lock(&rhp->rdev.stats.lock);
        rhp->rdev.stats.pd.cur--;
        mutex_unlock(&rhp->rdev.stats.lock);
-       kfree(php);
-       return 0;
 }
 
-static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
-                                     struct ib_ucontext *context,
-                                     struct ib_udata *udata)
+static int c4iw_allocate_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                           struct ib_udata *udata)
 {
-       struct c4iw_pd *php;
+       struct c4iw_pd *php = to_c4iw_pd(pd);
+       struct ib_device *ibdev = pd->device;
        u32 pdid;
        struct c4iw_dev *rhp;
 
@@ -237,12 +235,8 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
        rhp = (struct c4iw_dev *) ibdev;
        pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_table);
        if (!pdid)
-               return ERR_PTR(-EINVAL);
-       php = kzalloc(sizeof(*php), GFP_KERNEL);
-       if (!php) {
-               c4iw_put_resource(&rhp->rdev.resource.pdid_table, pdid);
-               return ERR_PTR(-ENOMEM);
-       }
+               return -EINVAL;
+
        php->pdid = pdid;
        php->rhp = rhp;
        if (context) {
@@ -250,7 +244,7 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
 
                if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
                        c4iw_deallocate_pd(&php->ibpd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
        mutex_lock(&rhp->rdev.stats.lock);
@@ -259,7 +253,7 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
                rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
        mutex_unlock(&rhp->rdev.stats.lock);
        pr_debug("pdid 0x%0x ptr 0x%p\n", pdid, php);
-       return &php->ibpd;
+       return 0;
 }
 
 static int c4iw_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
@@ -570,6 +564,7 @@ static const struct ib_device_ops c4iw_dev_ops = {
        .query_qp = c4iw_ib_query_qp,
        .reg_user_mr = c4iw_reg_user_mr,
        .req_notify_cq = c4iw_arm_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd),
 };
 
 void c4iw_register_device(struct work_struct *work)
index 8ca8d74dfb6a019acd27ad5ac2060c88d183991b..9ee86daf1700aa28fb9eb11bb3946f6e79c98764 100644 (file)
@@ -1114,10 +1114,9 @@ struct ib_ah *hns_roce_create_ah(struct ib_pd *pd,
 int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
 int hns_roce_destroy_ah(struct ib_ah *ah, u32 flags);
 
-struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
-                               struct ib_ucontext *context,
-                               struct ib_udata *udata);
-int hns_roce_dealloc_pd(struct ib_pd *pd);
+int hns_roce_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                     struct ib_udata *udata);
+void hns_roce_dealloc_pd(struct ib_pd *pd);
 
 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 fa08c22aad66b8aebd4b17ae81b4f67ac53fdf7c..a18b88c9599589ae51528a5295d3abbe19d7a1a2 100644 (file)
@@ -711,13 +711,14 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
        struct ib_qp_attr attr = { 0 };
        struct hns_roce_v1_priv *priv;
        struct hns_roce_qp *hr_qp;
+       struct ib_device *ibdev;
        struct ib_cq *cq;
        struct ib_pd *pd;
        union ib_gid dgid;
        u64 subnet_prefix;
        int attr_mask = 0;
+       int ret = -ENOMEM;
        int i, j;
-       int ret;
        u8 queue_en[HNS_ROCE_V1_RESV_QP] = { 0 };
        u8 phy_port;
        u8 port = 0;
@@ -742,12 +743,16 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
        free_mr->mr_free_cq->ib_cq.cq_context           = NULL;
        atomic_set(&free_mr->mr_free_cq->ib_cq.usecnt, 0);
 
-       pd = hns_roce_alloc_pd(&hr_dev->ib_dev, NULL, NULL);
-       if (IS_ERR(pd)) {
-               dev_err(dev, "Create pd for reserved loop qp failed!");
-               ret = -ENOMEM;
+       ibdev = &hr_dev->ib_dev;
+       pd = rdma_zalloc_drv_obj(ibdev, ib_pd);
+       if (pd)
+               goto alloc_mem_failed;
+
+       pd->device  = ibdev;
+       ret = hns_roce_alloc_pd(pd, NULL, NULL);
+       if (ret)
                goto alloc_pd_failed;
-       }
+
        free_mr->mr_free_pd = to_hr_pd(pd);
        free_mr->mr_free_pd->ibpd.device  = &hr_dev->ib_dev;
        free_mr->mr_free_pd->ibpd.uobject = NULL;
@@ -854,10 +859,12 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
                        dev_err(dev, "Destroy qp %d for mr free failed!\n", i);
        }
 
-       if (hns_roce_dealloc_pd(pd))
-               dev_err(dev, "Destroy pd for create_lp_qp failed!\n");
+       hns_roce_dealloc_pd(pd);
 
 alloc_pd_failed:
+       kfree(pd);
+
+alloc_mem_failed:
        if (hns_roce_ib_destroy_cq(cq))
                dev_err(dev, "Destroy cq for create_lp_qp failed!\n");
 
@@ -891,9 +898,7 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
        if (ret)
                dev_err(dev, "Destroy cq for mr_free failed(%d)!\n", ret);
 
-       ret = hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd);
-       if (ret)
-               dev_err(dev, "Destroy pd for mr_free failed(%d)!\n", ret);
+       hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd);
 }
 
 static int hns_roce_db_init(struct hns_roce_dev *hr_dev)
index 67a8c4333f4fbecc8034e5bea73a21969449b5c4..ccf10622586cea47f16898a5f516417c89f77e9d 100644 (file)
@@ -472,6 +472,7 @@ static const struct ib_device_ops hns_roce_dev_ops = {
        .query_pkey = hns_roce_query_pkey,
        .query_port = hns_roce_query_port,
        .reg_user_mr = hns_roce_reg_user_mr,
+       INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd),
 };
 
 static const struct ib_device_ops hns_roce_dev_mr_ops = {
index 4a29b2cb9bab87cceb50a0686d89cc1ddf5db477..b9b97c5e97e6fb68678ec079a237410bcc9b6fd2 100644 (file)
@@ -57,24 +57,19 @@ void hns_roce_cleanup_pd_table(struct hns_roce_dev *hr_dev)
        hns_roce_bitmap_cleanup(&hr_dev->pd_bitmap);
 }
 
-struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
-                               struct ib_ucontext *context,
-                               struct ib_udata *udata)
+int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                     struct ib_udata *udata)
 {
+       struct ib_device *ib_dev = ibpd->device;
        struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
        struct device *dev = hr_dev->dev;
-       struct hns_roce_pd *pd;
+       struct hns_roce_pd *pd = to_hr_pd(ibpd);
        int ret;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        ret = hns_roce_pd_alloc(to_hr_dev(ib_dev), &pd->pdn);
        if (ret) {
-               kfree(pd);
                dev_err(dev, "[alloc_pd]hns_roce_pd_alloc failed!\n");
-               return ERR_PTR(ret);
+               return ret;
        }
 
        if (context) {
@@ -83,21 +78,17 @@ struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
                if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
                        hns_roce_pd_free(to_hr_dev(ib_dev), pd->pdn);
                        dev_err(dev, "[alloc_pd]ib_copy_to_udata failed!\n");
-                       kfree(pd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
 
-       return &pd->ibpd;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(hns_roce_alloc_pd);
 
-int hns_roce_dealloc_pd(struct ib_pd *pd)
+void hns_roce_dealloc_pd(struct ib_pd *pd)
 {
        hns_roce_pd_free(to_hr_dev(pd->device), to_hr_pd(pd)->pdn);
-       kfree(to_hr_pd(pd));
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(hns_roce_dealloc_pd);
 
index 59e978141ad48ac0bf734216698abfc47657c93c..c5a881172524a6badd8f088850fb60c57120b1ce 100644 (file)
@@ -601,7 +601,6 @@ void i40iw_rem_pdusecount(struct i40iw_pd *iwpd, struct i40iw_device *iwdev)
        if (!atomic_dec_and_test(&iwpd->usecount))
                return;
        i40iw_free_resource(iwdev, iwdev->allocated_pds, iwpd->sc_pd.pd_id);
-       kfree(iwpd);
 }
 
 /**
index d4ab46dd9e6c7ebfec5b371528c9ccfefbe3362f..28449ad57b37216e3c7b6b4f19fa0dcb0cde1ea5 100644 (file)
@@ -312,16 +312,15 @@ static void i40iw_dealloc_push_page(struct i40iw_device *iwdev, struct i40iw_sc_
 
 /**
  * i40iw_alloc_pd - allocate protection domain
- * @ibdev: device pointer from stack
+ * @pd: PD pointer
  * @context: user context created during alloc
  * @udata: user data
  */
-static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
-                                   struct ib_ucontext *context,
-                                   struct ib_udata *udata)
+static int i40iw_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                         struct ib_udata *udata)
 {
-       struct i40iw_pd *iwpd;
-       struct i40iw_device *iwdev = to_iwdev(ibdev);
+       struct i40iw_pd *iwpd = to_iwpd(pd);
+       struct i40iw_device *iwdev = to_iwdev(pd->device);
        struct i40iw_sc_dev *dev = &iwdev->sc_dev;
        struct i40iw_alloc_pd_resp uresp;
        struct i40iw_sc_pd *sc_pd;
@@ -330,19 +329,13 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
        int err;
 
        if (iwdev->closing)
-               return ERR_PTR(-ENODEV);
+               return -ENODEV;
 
        err = i40iw_alloc_resource(iwdev, iwdev->allocated_pds,
                                   iwdev->max_pd, &pd_id, &iwdev->next_pd);
        if (err) {
                i40iw_pr_err("alloc resource failed\n");
-               return ERR_PTR(err);
-       }
-
-       iwpd = kzalloc(sizeof(*iwpd), GFP_KERNEL);
-       if (!iwpd) {
-               err = -ENOMEM;
-               goto free_res;
+               return err;
        }
 
        sc_pd = &iwpd->sc_pd;
@@ -361,25 +354,23 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
        }
 
        i40iw_add_pdusecount(iwpd);
-       return &iwpd->ibpd;
+       return 0;
+
 error:
-       kfree(iwpd);
-free_res:
        i40iw_free_resource(iwdev, iwdev->allocated_pds, pd_id);
-       return ERR_PTR(err);
+       return err;
 }
 
 /**
  * i40iw_dealloc_pd - deallocate pd
  * @ibpd: ptr of pd to be deallocated
  */
-static int i40iw_dealloc_pd(struct ib_pd *ibpd)
+static void i40iw_dealloc_pd(struct ib_pd *ibpd)
 {
        struct i40iw_pd *iwpd = to_iwpd(ibpd);
        struct i40iw_device *iwdev = to_iwdev(ibpd->device);
 
        i40iw_rem_pdusecount(iwpd, iwdev);
-       return 0;
 }
 
 /**
@@ -2750,6 +2741,7 @@ static const struct ib_device_ops i40iw_dev_ops = {
        .query_qp = i40iw_query_qp,
        .reg_user_mr = i40iw_reg_user_mr,
        .req_notify_cq = i40iw_req_notify_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, i40iw_pd, ibpd),
 };
 
 /**
index d66002a3100072ea597ebf65bad0d31da320e976..c0f6aea7ed7c4626e8409e4602441a83c9acf068 100644 (file)
@@ -1186,38 +1186,27 @@ static int mlx4_ib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
        }
 }
 
-static struct ib_pd *mlx4_ib_alloc_pd(struct ib_device *ibdev,
-                                     struct ib_ucontext *context,
-                                     struct ib_udata *udata)
+static int mlx4_ib_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                           struct ib_udata *udata)
 {
-       struct mlx4_ib_pd *pd;
+       struct mlx4_ib_pd *pd = to_mpd(ibpd);
+       struct ib_device *ibdev = ibpd->device;
        int err;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        err = mlx4_pd_alloc(to_mdev(ibdev)->dev, &pd->pdn);
-       if (err) {
-               kfree(pd);
-               return ERR_PTR(err);
-       }
+       if (err)
+               return err;
 
-       if (context)
-               if (ib_copy_to_udata(udata, &pd->pdn, sizeof (__u32))) {
-                       mlx4_pd_free(to_mdev(ibdev)->dev, pd->pdn);
-                       kfree(pd);
-                       return ERR_PTR(-EFAULT);
-               }
-       return &pd->ibpd;
+       if (context && ib_copy_to_udata(udata, &pd->pdn, sizeof(__u32))) {
+               mlx4_pd_free(to_mdev(ibdev)->dev, pd->pdn);
+               return -EFAULT;
+       }
+       return 0;
 }
 
-static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
+static void mlx4_ib_dealloc_pd(struct ib_pd *pd)
 {
        mlx4_pd_free(to_mdev(pd->device)->dev, to_mpd(pd)->pdn);
-       kfree(pd);
-
-       return 0;
 }
 
 static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev,
@@ -2580,6 +2569,7 @@ static const struct ib_device_ops mlx4_ib_dev_ops = {
        .req_notify_cq = mlx4_ib_arm_cq,
        .rereg_user_mr = mlx4_ib_rereg_user_mr,
        .resize_cq = mlx4_ib_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, mlx4_ib_pd, ibpd),
 };
 
 static const struct ib_device_ops mlx4_ib_dev_wq_ops = {
index 76d6c2557d0c232e469108acd7604e39c5c9f284..f9cddc6f2ab609285feb84bf71b9d11644016b27 100644 (file)
@@ -2280,30 +2280,24 @@ int mlx5_ib_dealloc_dm(struct ib_dm *ibdm)
        return 0;
 }
 
-static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
-                                     struct ib_ucontext *context,
-                                     struct ib_udata *udata)
+static int mlx5_ib_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                           struct ib_udata *udata)
 {
+       struct mlx5_ib_pd *pd = to_mpd(ibpd);
+       struct ib_device *ibdev = ibpd->device;
        struct mlx5_ib_alloc_pd_resp resp;
-       struct mlx5_ib_pd *pd;
        int err;
        u32 out[MLX5_ST_SZ_DW(alloc_pd_out)] = {};
        u32 in[MLX5_ST_SZ_DW(alloc_pd_in)]   = {};
        u16 uid = 0;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        uid = context ? to_mucontext(context)->devx_uid : 0;
        MLX5_SET(alloc_pd_in, in, opcode, MLX5_CMD_OP_ALLOC_PD);
        MLX5_SET(alloc_pd_in, in, uid, uid);
        err = mlx5_cmd_exec(to_mdev(ibdev)->mdev, in, sizeof(in),
                            out, sizeof(out));
-       if (err) {
-               kfree(pd);
-               return ERR_PTR(err);
-       }
+       if (err)
+               return err;
 
        pd->pdn = MLX5_GET(alloc_pd_out, out, pd);
        pd->uid = uid;
@@ -2311,23 +2305,19 @@ static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
                resp.pdn = pd->pdn;
                if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
                        mlx5_cmd_dealloc_pd(to_mdev(ibdev)->mdev, pd->pdn, uid);
-                       kfree(pd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
 
-       return &pd->ibpd;
+       return 0;
 }
 
-static int mlx5_ib_dealloc_pd(struct ib_pd *pd)
+static void mlx5_ib_dealloc_pd(struct ib_pd *pd)
 {
        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);
-       kfree(mpd);
-
-       return 0;
 }
 
 enum {
@@ -4680,23 +4670,28 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
 {
        struct ib_srq_init_attr attr;
        struct mlx5_ib_dev *dev;
+       struct ib_device *ibdev;
        struct ib_cq_init_attr cq_attr = {.cqe = 1};
        int port;
        int ret = 0;
 
        dev = container_of(devr, struct mlx5_ib_dev, devr);
+       ibdev = &dev->ib_dev;
 
        mutex_init(&devr->mutex);
 
-       devr->p0 = mlx5_ib_alloc_pd(&dev->ib_dev, NULL, NULL);
-       if (IS_ERR(devr->p0)) {
-               ret = PTR_ERR(devr->p0);
-               goto error0;
-       }
-       devr->p0->device  = &dev->ib_dev;
+       devr->p0 = rdma_zalloc_drv_obj(ibdev, ib_pd);
+       if (!devr->p0)
+               return -ENOMEM;
+
+       devr->p0->device  = ibdev;
        devr->p0->uobject = NULL;
        atomic_set(&devr->p0->usecnt, 0);
 
+       ret = mlx5_ib_alloc_pd(devr->p0, NULL, NULL);
+       if (ret)
+               goto error0;
+
        devr->c0 = mlx5_ib_create_cq(&dev->ib_dev, &cq_attr, NULL, NULL);
        if (IS_ERR(devr->c0)) {
                ret = PTR_ERR(devr->c0);
@@ -4794,6 +4789,7 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
 error1:
        mlx5_ib_dealloc_pd(devr->p0);
 error0:
+       kfree(devr->p0);
        return ret;
 }
 
@@ -4809,6 +4805,7 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
        mlx5_ib_dealloc_xrcd(devr->x1);
        mlx5_ib_destroy_cq(devr->c0);
        mlx5_ib_dealloc_pd(devr->p0);
+       kfree(devr->p0);
 
        /* Make sure no change P_Key work items are still executing */
        for (port = 0; port < dev->num_ports; ++port)
@@ -5938,6 +5935,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
        .req_notify_cq = mlx5_ib_arm_cq,
        .rereg_user_mr = mlx5_ib_rereg_user_mr,
        .resize_cq = mlx5_ib_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd),
 };
 
 static const struct ib_device_ops mlx5_ib_dev_flow_ipsec_ops = {
index 1bb67562c8c88caa578044dea9112f5f5945ba03..2c754bc226f3acef329ca39349473c2278f47f43 100644 (file)
@@ -374,40 +374,30 @@ static int mthca_mmap_uar(struct ib_ucontext *context,
        return 0;
 }
 
-static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
-                                   struct ib_ucontext *context,
-                                   struct ib_udata *udata)
+static int mthca_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                         struct ib_udata *udata)
 {
-       struct mthca_pd *pd;
+       struct ib_device *ibdev = ibpd->device;
+       struct mthca_pd *pd = to_mpd(ibpd);
        int err;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        err = mthca_pd_alloc(to_mdev(ibdev), !context, pd);
-       if (err) {
-               kfree(pd);
-               return ERR_PTR(err);
-       }
+       if (err)
+               return err;
 
        if (context) {
                if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
                        mthca_pd_free(to_mdev(ibdev), pd);
-                       kfree(pd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
 
-       return &pd->ibpd;
+       return 0;
 }
 
-static int mthca_dealloc_pd(struct ib_pd *pd)
+static void mthca_dealloc_pd(struct ib_pd *pd)
 {
        mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
-       kfree(pd);
-
-       return 0;
 }
 
 static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
@@ -1228,6 +1218,7 @@ static const struct ib_device_ops mthca_dev_ops = {
        .query_qp = mthca_query_qp,
        .reg_user_mr = mthca_reg_user_mr,
        .resize_cq = mthca_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, mthca_pd, ibpd),
 };
 
 static const struct ib_device_ops mthca_dev_arbel_srq_ops = {
index 6eb991d4003581a9e413a1d4d935ef3686265958..f18b28ae4bd9037f5e2169fbd0320e9a38c5b471 100644 (file)
@@ -658,10 +658,11 @@ static int nes_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 /**
  * nes_alloc_pd
  */
-static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
-               struct ib_ucontext *context, struct ib_udata *udata)
+static int nes_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                       struct ib_udata *udata)
 {
-       struct nes_pd *nespd;
+       struct ib_device *ibdev = pd->device;
+       struct nes_pd *nespd = to_nespd(pd);
        struct nes_vnic *nesvnic = to_nesvnic(ibdev);
        struct nes_device *nesdev = nesvnic->nesdev;
        struct nes_adapter *nesadapter = nesdev->nesadapter;
@@ -676,15 +677,8 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
 
        err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds,
                        nesadapter->max_pd, &pd_num, &nesadapter->next_pd, NES_RESOURCE_PD);
-       if (err) {
-               return ERR_PTR(err);
-       }
-
-       nespd = kzalloc(sizeof (struct nes_pd), GFP_KERNEL);
-       if (!nespd) {
-               nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num);
-               return ERR_PTR(-ENOMEM);
-       }
+       if (err)
+               return err;
 
        nes_debug(NES_DBG_PD, "Allocating PD (%p) for ib device %s\n",
                        nespd, dev_name(&nesvnic->nesibdev->ibdev.dev));
@@ -700,16 +694,14 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
                if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) {
                        nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n");
                        nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num);
-                       kfree(nespd);
-                       return ERR_PTR(-ENOMEM);
+                       return -ENOMEM;
                }
 
                uresp.pd_id = nespd->pd_id;
                uresp.mmap_db_index = nespd->mmap_db_index;
                if (ib_copy_to_udata(udata, &uresp, sizeof (struct nes_alloc_pd_resp))) {
                        nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num);
-                       kfree(nespd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
 
                set_bit(nespd->mmap_db_index, nesucontext->allocated_doorbells);
@@ -718,14 +710,14 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
        }
 
        nes_debug(NES_DBG_PD, "PD%u structure located @%p.\n", nespd->pd_id, nespd);
-       return &nespd->ibpd;
+       return 0;
 }
 
 
 /**
  * nes_dealloc_pd
  */
-static int nes_dealloc_pd(struct ib_pd *ibpd)
+static void nes_dealloc_pd(struct ib_pd *ibpd)
 {
        struct nes_ucontext *nesucontext;
        struct nes_pd *nespd = to_nespd(ibpd);
@@ -748,9 +740,6 @@ static int nes_dealloc_pd(struct ib_pd *ibpd)
                        nespd->pd_id, nespd);
        nes_free_resource(nesadapter, nesadapter->allocated_pds,
                        (nespd->pd_id-nesadapter->base_pd)>>(PAGE_SHIFT-12));
-       kfree(nespd);
-
-       return 0;
 }
 
 
@@ -3658,6 +3647,7 @@ static const struct ib_device_ops nes_dev_ops = {
        .query_qp = nes_query_qp,
        .reg_user_mr = nes_reg_user_mr,
        .req_notify_cq = nes_req_notify_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, nes_pd, ibpd),
 };
 
 /**
index 88970a6bb555792a4f6061bd12c676c884eb74c1..0de83c92691fbb74d0b95b92c0563dd66c69f4d1 100644 (file)
@@ -179,6 +179,7 @@ static const struct ib_device_ops ocrdma_dev_ops = {
        .reg_user_mr = ocrdma_reg_user_mr,
        .req_notify_cq = ocrdma_arm_cq,
        .resize_cq = ocrdma_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, ocrdma_pd, ibpd),
 };
 
 static const struct ib_device_ops ocrdma_dev_srq_ops = {
index 2a62936bef4d3ac7f3eb6839791b17777e2fbf63..980ba97188ffdc5c18953bee4a35f3bc6c6edeae 100644 (file)
@@ -367,17 +367,12 @@ static int ocrdma_get_pd_num(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
        return status;
 }
 
-static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
-                                         struct ocrdma_ucontext *uctx,
-                                         struct ib_udata *udata)
+static int _ocrdma_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd,
+                           struct ocrdma_ucontext *uctx,
+                           struct ib_udata *udata)
 {
-       struct ocrdma_pd *pd = NULL;
        int status;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        if (udata && uctx && dev->attr.max_dpp_pds) {
                pd->dpp_enabled =
                        ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R;
@@ -386,15 +381,8 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
                                           dev->attr.wqe_size) : 0;
        }
 
-       if (dev->pd_mgr->pd_prealloc_valid) {
-               status = ocrdma_get_pd_num(dev, pd);
-               if (status == 0) {
-                       return pd;
-               } else {
-                       kfree(pd);
-                       return ERR_PTR(status);
-               }
-       }
+       if (dev->pd_mgr->pd_prealloc_valid)
+               return ocrdma_get_pd_num(dev, pd);
 
 retry:
        status = ocrdma_mbx_alloc_pd(dev, pd);
@@ -403,13 +391,11 @@ static struct ocrdma_pd *_ocrdma_alloc_pd(struct ocrdma_dev *dev,
                        pd->dpp_enabled = false;
                        pd->num_dpp_qp = 0;
                        goto retry;
-               } else {
-                       kfree(pd);
-                       return ERR_PTR(status);
                }
+               return status;
        }
 
-       return pd;
+       return 0;
 }
 
 static inline int is_ucontext_pd(struct ocrdma_ucontext *uctx,
@@ -418,30 +404,33 @@ static inline int is_ucontext_pd(struct ocrdma_ucontext *uctx,
        return (uctx->cntxt_pd == pd);
 }
 
-static int _ocrdma_dealloc_pd(struct ocrdma_dev *dev,
+static void _ocrdma_dealloc_pd(struct ocrdma_dev *dev,
                              struct ocrdma_pd *pd)
 {
-       int status;
-
        if (dev->pd_mgr->pd_prealloc_valid)
-               status = ocrdma_put_pd_num(dev, pd->id, pd->dpp_enabled);
+               ocrdma_put_pd_num(dev, pd->id, pd->dpp_enabled);
        else
-               status = ocrdma_mbx_dealloc_pd(dev, pd);
-
-       kfree(pd);
-       return status;
+               ocrdma_mbx_dealloc_pd(dev, pd);
 }
 
 static int ocrdma_alloc_ucontext_pd(struct ocrdma_dev *dev,
                                    struct ocrdma_ucontext *uctx,
                                    struct ib_udata *udata)
 {
-       int status = 0;
+       struct ib_device *ibdev = &dev->ibdev;
+       struct ib_pd *pd;
+       int status;
+
+       pd = rdma_zalloc_drv_obj(ibdev, ib_pd);
+       if (!pd)
+               return -ENOMEM;
+
+       pd->device  = ibdev;
+       uctx->cntxt_pd = get_ocrdma_pd(pd);
 
-       uctx->cntxt_pd = _ocrdma_alloc_pd(dev, uctx, udata);
-       if (IS_ERR(uctx->cntxt_pd)) {
-               status = PTR_ERR(uctx->cntxt_pd);
-               uctx->cntxt_pd = NULL;
+       status = _ocrdma_alloc_pd(dev, uctx->cntxt_pd, uctx, udata);
+       if (status) {
+               kfree(uctx->cntxt_pd);
                goto err;
        }
 
@@ -460,6 +449,7 @@ static int ocrdma_dealloc_ucontext_pd(struct ocrdma_ucontext *uctx)
                pr_err("%s(%d) Freeing in use pdid=0x%x.\n",
                       __func__, dev->id, pd->id);
        }
+       kfree(uctx->cntxt_pd);
        uctx->cntxt_pd = NULL;
        (void)_ocrdma_dealloc_pd(dev, pd);
        return 0;
@@ -537,6 +527,7 @@ struct ib_ucontext *ocrdma_alloc_ucontext(struct ib_device *ibdev,
        return &ctx->ibucontext;
 
 cpy_err:
+       ocrdma_dealloc_ucontext_pd(ctx);
 pd_err:
        ocrdma_del_mmap(ctx, ctx->ah_tbl.pa, ctx->ah_tbl.len);
 map_err:
@@ -658,10 +649,10 @@ static int ocrdma_copy_pd_uresp(struct ocrdma_dev *dev, struct ocrdma_pd *pd,
        return status;
 }
 
-struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
-                             struct ib_ucontext *context,
-                             struct ib_udata *udata)
+int ocrdma_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                   struct ib_udata *udata)
 {
+       struct ib_device *ibdev = ibpd->device;
        struct ocrdma_dev *dev = get_ocrdma_dev(ibdev);
        struct ocrdma_pd *pd;
        struct ocrdma_ucontext *uctx = NULL;
@@ -677,11 +668,10 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
                }
        }
 
-       pd = _ocrdma_alloc_pd(dev, uctx, udata);
-       if (IS_ERR(pd)) {
-               status = PTR_ERR(pd);
+       pd = get_ocrdma_pd(ibpd);
+       status = _ocrdma_alloc_pd(dev, pd, uctx, udata);
+       if (status)
                goto exit;
-       }
 
 pd_mapping:
        if (udata && context) {
@@ -689,25 +679,22 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
                if (status)
                        goto err;
        }
-       return &pd->ibpd;
+       return 0;
 
 err:
-       if (is_uctx_pd) {
+       if (is_uctx_pd)
                ocrdma_release_ucontext_pd(uctx);
-       } else {
-               if (_ocrdma_dealloc_pd(dev, pd))
-                       pr_err("%s: _ocrdma_dealloc_pd() failed\n", __func__);
-       }
+       else
+               _ocrdma_dealloc_pd(dev, pd);
 exit:
-       return ERR_PTR(status);
+       return status;
 }
 
-int ocrdma_dealloc_pd(struct ib_pd *ibpd)
+void ocrdma_dealloc_pd(struct ib_pd *ibpd)
 {
        struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
        struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
        struct ocrdma_ucontext *uctx = NULL;
-       int status = 0;
        u64 usr_db;
 
        uctx = pd->uctx;
@@ -721,11 +708,10 @@ int ocrdma_dealloc_pd(struct ib_pd *ibpd)
 
                if (is_ucontext_pd(uctx, pd)) {
                        ocrdma_release_ucontext_pd(uctx);
-                       return status;
+                       return;
                }
        }
-       status = _ocrdma_dealloc_pd(dev, pd);
-       return status;
+       _ocrdma_dealloc_pd(dev, pd);
 }
 
 static int ocrdma_alloc_lkey(struct ocrdma_dev *dev, struct ocrdma_mr *mr,
index b69cfdce797093b0411f500043ae2fdd2d487add..1fd66721c9306d49161845cfbd6adeecd7f79df3 100644 (file)
@@ -70,9 +70,9 @@ int ocrdma_dealloc_ucontext(struct ib_ucontext *);
 
 int ocrdma_mmap(struct ib_ucontext *, struct vm_area_struct *vma);
 
-struct ib_pd *ocrdma_alloc_pd(struct ib_device *,
-                             struct ib_ucontext *, struct ib_udata *);
-int ocrdma_dealloc_pd(struct ib_pd *pd);
+int ocrdma_alloc_pd(struct ib_pd *pd, struct ib_ucontext *uctx,
+                   struct ib_udata *udata);
+void ocrdma_dealloc_pd(struct ib_pd *pd);
 
 struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev,
                               const struct ib_cq_init_attr *attr,
index 878e9e23652bf0168db86a8e3bdfc9e0dc004510..44ce4989dcef46168c0c1f55612cfe2bd9461521 100644 (file)
@@ -239,6 +239,7 @@ static const struct ib_device_ops qedr_dev_ops = {
        .reg_user_mr = qedr_reg_user_mr,
        .req_notify_cq = qedr_arm_cq,
        .resize_cq = qedr_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, qedr_pd, ibpd),
 };
 
 static int qedr_register_device(struct qedr_dev *dev)
index 989f08633fbef2ffe3f537990f1ee537f63d33b6..a06d2258394a4f6553d7c4176c7f7999d45d764a 100644 (file)
@@ -450,11 +450,12 @@ int qedr_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
                                  vma->vm_page_prot);
 }
 
-struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
-                           struct ib_ucontext *context, struct ib_udata *udata)
+int qedr_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                 struct ib_udata *udata)
 {
+       struct ib_device *ibdev = ibpd->device;
        struct qedr_dev *dev = get_qedr_dev(ibdev);
-       struct qedr_pd *pd;
+       struct qedr_pd *pd = get_qedr_pd(ibpd);
        u16 pd_id;
        int rc;
 
@@ -463,16 +464,12 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
 
        if (!dev->rdma_ctx) {
                DP_ERR(dev, "invalid RDMA context\n");
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        rc = dev->ops->rdma_alloc_pd(dev->rdma_ctx, &pd_id);
        if (rc)
-               goto err;
+               return rc;
 
        pd->pd_id = pd_id;
 
@@ -485,36 +482,23 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
                if (rc) {
                        DP_ERR(dev, "copy error pd_id=0x%x.\n", pd_id);
                        dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd_id);
-                       goto err;
+                       return rc;
                }
 
                pd->uctx = get_qedr_ucontext(context);
                pd->uctx->pd = pd;
        }
 
-       return &pd->ibpd;
-
-err:
-       kfree(pd);
-       return ERR_PTR(rc);
+       return 0;
 }
 
-int qedr_dealloc_pd(struct ib_pd *ibpd)
+void qedr_dealloc_pd(struct ib_pd *ibpd)
 {
        struct qedr_dev *dev = get_qedr_dev(ibpd->device);
        struct qedr_pd *pd = get_qedr_pd(ibpd);
 
-       if (!pd) {
-               pr_err("Invalid PD received in dealloc_pd\n");
-               return -EINVAL;
-       }
-
        DP_DEBUG(dev, QEDR_MSG_INIT, "Deallocating PD %d\n", pd->pd_id);
        dev->ops->rdma_dealloc_pd(dev->rdma_ctx, pd->pd_id);
-
-       kfree(pd);
-
-       return 0;
 }
 
 static void qedr_free_pbl(struct qedr_dev *dev,
index 1852b7012bf4f3757eba893b29cbf5523d442fc3..97a6ff3f9afb223c46fa3da6190053ae0673d671 100644 (file)
@@ -47,9 +47,9 @@ struct ib_ucontext *qedr_alloc_ucontext(struct ib_device *, struct ib_udata *);
 int qedr_dealloc_ucontext(struct ib_ucontext *);
 
 int qedr_mmap(struct ib_ucontext *, struct vm_area_struct *vma);
-struct ib_pd *qedr_alloc_pd(struct ib_device *,
-                           struct ib_ucontext *, struct ib_udata *);
-int qedr_dealloc_pd(struct ib_pd *pd);
+int qedr_alloc_pd(struct ib_pd *pd, struct ib_ucontext *uctx,
+                 struct ib_udata *udata);
+void qedr_dealloc_pd(struct ib_pd *pd);
 
 struct ib_cq *qedr_create_cq(struct ib_device *ibdev,
                             const struct ib_cq_init_attr *attr,
index 1ec155823716026b729320461924c6b4a3fa381e..256ad2f236c869748f489e2b5f01e410df6e10b8 100644 (file)
@@ -352,6 +352,7 @@ static const struct ib_device_ops usnic_dev_ops = {
        .query_port = usnic_ib_query_port,
        .query_qp = usnic_ib_query_qp,
        .reg_user_mr = usnic_ib_reg_mr,
+       INIT_RDMA_OBJ_SIZE(ib_pd, usnic_ib_pd, ibpd),
 };
 
 /* Start of PF discovery section */
index 9dea18106247910a32c73777989055638bca13cd..0ced89b514483970d42f75492a4643e5e6f281b8 100644 (file)
@@ -456,37 +456,23 @@ int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
        return 0;
 }
 
-struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
-                                       struct ib_ucontext *context,
-                                       struct ib_udata *udata)
+int usnic_ib_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                     struct ib_udata *udata)
 {
-       struct usnic_ib_pd *pd;
+       struct usnic_ib_pd *pd = to_upd(ibpd);
        void *umem_pd;
 
-       usnic_dbg("\n");
-
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd)
-               return ERR_PTR(-ENOMEM);
-
        umem_pd = pd->umem_pd = usnic_uiom_alloc_pd();
        if (IS_ERR_OR_NULL(umem_pd)) {
-               kfree(pd);
-               return ERR_PTR(umem_pd ? PTR_ERR(umem_pd) : -ENOMEM);
+               return umem_pd ? PTR_ERR(umem_pd) : -ENOMEM;
        }
 
-       usnic_info("domain 0x%p allocated for context 0x%p and device %s\n",
-                  pd, context, dev_name(&ibdev->dev));
-       return &pd->ibpd;
+       return 0;
 }
 
-int usnic_ib_dealloc_pd(struct ib_pd *pd)
+void usnic_ib_dealloc_pd(struct ib_pd *pd)
 {
-       usnic_info("freeing domain 0x%p\n", pd);
-
        usnic_uiom_dealloc_pd((to_upd(pd))->umem_pd);
-       kfree(pd);
-       return 0;
 }
 
 struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
index 99a6d81c2bcd02423faaabae0629a7f58efbab80..44a9d2f82bf5082fc37a66e5eae57110d475c552 100644 (file)
@@ -51,10 +51,9 @@ int usnic_ib_query_gid(struct ib_device *ibdev, u8 port, int index,
 struct net_device *usnic_get_netdev(struct ib_device *device, u8 port_num);
 int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
                                u16 *pkey);
-struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
-                               struct ib_ucontext *context,
-                               struct ib_udata *udata);
-int usnic_ib_dealloc_pd(struct ib_pd *pd);
+int usnic_ib_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                     struct ib_udata *udata);
+void usnic_ib_dealloc_pd(struct ib_pd *pd);
 struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd,
                                        struct ib_qp_init_attr *init_attr,
                                        struct ib_udata *udata);
index e582beaf94305c61f7cbc30e5f7a68cf9eac0f8c..47e653d2495c41611f3448489ee97d7025fb59d5 100644 (file)
@@ -195,6 +195,7 @@ static const struct ib_device_ops pvrdma_dev_ops = {
        .query_qp = pvrdma_query_qp,
        .reg_user_mr = pvrdma_reg_user_mr,
        .req_notify_cq = pvrdma_req_notify_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, pvrdma_pd, ibpd),
 };
 
 static const struct ib_device_ops pvrdma_dev_srq_ops = {
index fafb2add3b442458a3db30a42b3bcf146a1f731b..f44220f72e053dc1312692ea2ef54b21809b897d 100644 (file)
@@ -438,37 +438,29 @@ int pvrdma_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma)
 
 /**
  * pvrdma_alloc_pd - allocate protection domain
- * @ibdev: the IB device
+ * @ibpd: PD pointer
  * @context: user context
  * @udata: user data
  *
  * @return: the ib_pd protection domain pointer on success, otherwise errno.
  */
-struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
-                             struct ib_ucontext *context,
-                             struct ib_udata *udata)
+int pvrdma_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                   struct ib_udata *udata)
 {
-       struct pvrdma_pd *pd;
+       struct ib_device *ibdev = ibpd->device;
+       struct pvrdma_pd *pd = to_vpd(ibpd);
        struct pvrdma_dev *dev = to_vdev(ibdev);
-       union pvrdma_cmd_req req;
-       union pvrdma_cmd_resp rsp;
+       union pvrdma_cmd_req req = {};
+       union pvrdma_cmd_resp rsp = {};
        struct pvrdma_cmd_create_pd *cmd = &req.create_pd;
        struct pvrdma_cmd_create_pd_resp *resp = &rsp.create_pd_resp;
        struct pvrdma_alloc_pd_resp pd_resp = {0};
        int ret;
-       void *ptr;
 
        /* Check allowed max pds */
        if (!atomic_add_unless(&dev->num_pds, 1, dev->dsr->caps.max_pd))
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd) {
-               ptr = ERR_PTR(-ENOMEM);
-               goto err;
-       }
-
-       memset(cmd, 0, sizeof(*cmd));
        cmd->hdr.cmd = PVRDMA_CMD_CREATE_PD;
        cmd->ctx_handle = (context) ? to_vucontext(context)->ctx_handle : 0;
        ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_PD_RESP);
@@ -476,8 +468,7 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
                dev_warn(&dev->pdev->dev,
                         "failed to allocate protection domain, error: %d\n",
                         ret);
-               ptr = ERR_PTR(ret);
-               goto freepd;
+               goto err;
        }
 
        pd->privileged = !context;
@@ -490,18 +481,16 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
                        dev_warn(&dev->pdev->dev,
                                 "failed to copy back protection domain\n");
                        pvrdma_dealloc_pd(&pd->ibpd);
-                       return ERR_PTR(-EFAULT);
+                       return -EFAULT;
                }
        }
 
        /* u32 pd handle */
-       return &pd->ibpd;
+       return 0;
 
-freepd:
-       kfree(pd);
 err:
        atomic_dec(&dev->num_pds);
-       return ptr;
+       return ret;
 }
 
 /**
@@ -510,14 +499,13 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
  *
  * @return: 0 on success, otherwise errno.
  */
-int pvrdma_dealloc_pd(struct ib_pd *pd)
+void pvrdma_dealloc_pd(struct ib_pd *pd)
 {
        struct pvrdma_dev *dev = to_vdev(pd->device);
-       union pvrdma_cmd_req req;
+       union pvrdma_cmd_req req = {};
        struct pvrdma_cmd_destroy_pd *cmd = &req.destroy_pd;
        int ret;
 
-       memset(cmd, 0, sizeof(*cmd));
        cmd->hdr.cmd = PVRDMA_CMD_DESTROY_PD;
        cmd->pd_handle = to_vpd(pd)->pd_handle;
 
@@ -527,10 +515,7 @@ int pvrdma_dealloc_pd(struct ib_pd *pd)
                         "could not dealloc protection domain, error: %d\n",
                         ret);
 
-       kfree(to_vpd(pd));
        atomic_dec(&dev->num_pds);
-
-       return 0;
 }
 
 /**
index f7f758d601105b6385947808150b54aa7b0da347..ed91baad1ffafc78e8148c957d428d7fbcdce949 100644 (file)
@@ -399,10 +399,9 @@ int pvrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev,
                                          struct ib_udata *udata);
 int pvrdma_dealloc_ucontext(struct ib_ucontext *context);
-struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
-                             struct ib_ucontext *context,
-                             struct ib_udata *udata);
-int pvrdma_dealloc_pd(struct ib_pd *ibpd);
+int pvrdma_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                   struct ib_udata *udata);
+void pvrdma_dealloc_pd(struct ib_pd *ibpd);
 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 dcc1870b8d23dba66e1e5368edc104113cbfbf84..6033054b22fae4594447e02e6ddcdd40950776a3 100644 (file)
@@ -50,7 +50,7 @@
 
 /**
  * rvt_alloc_pd - allocate a protection domain
- * @ibdev: ib device
+ * @ibpd: PD
  * @context: optional user context
  * @udata: optional user data
  *
  *
  * Return: 0 on success
  */
-struct ib_pd *rvt_alloc_pd(struct ib_device *ibdev,
-                          struct ib_ucontext *context,
-                          struct ib_udata *udata)
+int rvt_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                struct ib_udata *udata)
 {
+       struct ib_device *ibdev = ibpd->device;
        struct rvt_dev_info *dev = ib_to_rvt(ibdev);
-       struct rvt_pd *pd;
-       struct ib_pd *ret;
+       struct rvt_pd *pd = ibpd_to_rvtpd(ibpd);
+       int ret = 0;
 
-       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
-       if (!pd) {
-               ret = ERR_PTR(-ENOMEM);
-               goto bail;
-       }
        /*
         * While we could continue allocating protecetion domains, being
         * constrained only by system resources. The IBTA spec defines that
@@ -81,8 +76,7 @@ struct ib_pd *rvt_alloc_pd(struct ib_device *ibdev,
        spin_lock(&dev->n_pds_lock);
        if (dev->n_pds_allocated == dev->dparms.props.max_pd) {
                spin_unlock(&dev->n_pds_lock);
-               kfree(pd);
-               ret = ERR_PTR(-ENOMEM);
+               ret = -ENOMEM;
                goto bail;
        }
 
@@ -92,8 +86,6 @@ struct ib_pd *rvt_alloc_pd(struct ib_device *ibdev,
        /* ib_alloc_pd() will initialize pd->ibpd. */
        pd->user = !!udata;
 
-       ret = &pd->ibpd;
-
 bail:
        return ret;
 }
@@ -104,16 +96,11 @@ struct ib_pd *rvt_alloc_pd(struct ib_device *ibdev,
  *
  * Return: always 0
  */
-int rvt_dealloc_pd(struct ib_pd *ibpd)
+void rvt_dealloc_pd(struct ib_pd *ibpd)
 {
-       struct rvt_pd *pd = ibpd_to_rvtpd(ibpd);
        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);
-
-       kfree(pd);
-
-       return 0;
 }
index 1892ca4a9746fb598d0c2120c90f4affd5ad1249..7a887e4a45e7a5ac9b766856ae185ebe0f9af2c9 100644 (file)
@@ -50,9 +50,8 @@
 
 #include <rdma/rdma_vt.h>
 
-struct ib_pd *rvt_alloc_pd(struct ib_device *ibdev,
-                          struct ib_ucontext *context,
-                          struct ib_udata *udata);
-int rvt_dealloc_pd(struct ib_pd *ibpd);
+int rvt_alloc_pd(struct ib_pd *pd, struct ib_ucontext *context,
+                struct ib_udata *udata);
+void rvt_dealloc_pd(struct ib_pd *ibpd);
 
 #endif          /* DEF_RDMAVTPD_H */
index b3f0c557892515630d0ffbf592186855b25c5505..a19832c73d5a41ef8f0391d5a685d50d851ec808 100644 (file)
@@ -436,6 +436,7 @@ static const struct ib_device_ops rvt_dev_ops = {
        .req_notify_cq = rvt_req_notify_cq,
        .resize_cq = rvt_resize_cq,
        .unmap_fmr = rvt_unmap_fmr,
+       INIT_RDMA_OBJ_SIZE(ib_pd, rvt_pd, ibpd),
 };
 
 static noinline int check_support(struct rvt_dev_info *rdi, int verb)
index b5c91df220473f922d23ae3bdbb460e4d02c5c00..cd3f14629ba873eb9e3dc242195399ddb47d6e4e 100644 (file)
@@ -46,6 +46,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = {
        [RXE_TYPE_PD] = {
                .name           = "rxe-pd",
                .size           = sizeof(struct rxe_pd),
+               .flags          = RXE_POOL_NO_ALLOC,
        },
        [RXE_TYPE_AH] = {
                .name           = "rxe-ah",
@@ -119,8 +120,10 @@ static void rxe_cache_clean(size_t cnt)
 
        for (i = 0; i < cnt; i++) {
                type = &rxe_type_info[i];
-               kmem_cache_destroy(type->cache);
-               type->cache = NULL;
+               if (!(type->flags & RXE_POOL_NO_ALLOC)) {
+                       kmem_cache_destroy(type->cache);
+                       type->cache = NULL;
+               }
        }
 }
 
@@ -134,14 +137,17 @@ int rxe_cache_init(void)
        for (i = 0; i < RXE_NUM_TYPES; i++) {
                type = &rxe_type_info[i];
                size = ALIGN(type->size, RXE_POOL_ALIGN);
-               type->cache = kmem_cache_create(type->name, size,
-                               RXE_POOL_ALIGN,
-                               RXE_POOL_CACHE_FLAGS, NULL);
-               if (!type->cache) {
-                       pr_err("Unable to init kmem cache for %s\n",
-                              type->name);
-                       err = -ENOMEM;
-                       goto err1;
+               if (!(type->flags & RXE_POOL_NO_ALLOC)) {
+                       type->cache =
+                               kmem_cache_create(type->name, size,
+                                                 RXE_POOL_ALIGN,
+                                                 RXE_POOL_CACHE_FLAGS, NULL);
+                       if (!type->cache) {
+                               pr_err("Unable to init kmem cache for %s\n",
+                                      type->name);
+                               err = -ENOMEM;
+                               goto err1;
+                       }
                }
        }
 
@@ -415,6 +421,37 @@ void *rxe_alloc(struct rxe_pool *pool)
        return NULL;
 }
 
+int rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_entry *elem)
+{
+       unsigned long flags;
+
+       might_sleep_if(!(pool->flags & RXE_POOL_ATOMIC));
+
+       read_lock_irqsave(&pool->pool_lock, flags);
+       if (pool->state != RXE_POOL_STATE_VALID) {
+               read_unlock_irqrestore(&pool->pool_lock, flags);
+               return -EINVAL;
+       }
+       kref_get(&pool->ref_cnt);
+       read_unlock_irqrestore(&pool->pool_lock, flags);
+
+       kref_get(&pool->rxe->ref_cnt);
+
+       if (atomic_inc_return(&pool->num_elem) > pool->max_elem)
+               goto out_put_pool;
+
+       elem->pool = pool;
+       kref_init(&elem->ref_cnt);
+
+       return 0;
+
+out_put_pool:
+       atomic_dec(&pool->num_elem);
+       rxe_dev_put(pool->rxe);
+       rxe_pool_put(pool);
+       return -EINVAL;
+}
+
 void rxe_elem_release(struct kref *kref)
 {
        struct rxe_pool_entry *elem =
@@ -424,7 +461,8 @@ void rxe_elem_release(struct kref *kref)
        if (pool->cleanup)
                pool->cleanup(elem);
 
-       kmem_cache_free(pool_cache(pool), elem);
+       if (!(pool->flags & RXE_POOL_NO_ALLOC))
+               kmem_cache_free(pool_cache(pool), elem);
        atomic_dec(&pool->num_elem);
        rxe_dev_put(pool->rxe);
        rxe_pool_put(pool);
index 72968c29e01f7c6f0bfad82bf2b5f337ea88131a..2f2cff1cbe439833a29a405da8957bec01e32ced 100644 (file)
@@ -41,6 +41,7 @@ enum rxe_pool_flags {
        RXE_POOL_ATOMIC         = BIT(0),
        RXE_POOL_INDEX          = BIT(1),
        RXE_POOL_KEY            = BIT(2),
+       RXE_POOL_NO_ALLOC       = BIT(4),
 };
 
 enum rxe_elem_type {
@@ -131,6 +132,9 @@ void rxe_pool_cleanup(struct rxe_pool *pool);
 /* allocate an object from pool */
 void *rxe_alloc(struct rxe_pool *pool);
 
+/* connect already allocated object to pool */
+int rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_entry *elem);
+
 /* assign an index to an indexed object and insert object into
  *  pool's rb tree
  */
index cc5a05124ece256143b277aaac4b6d55879154c8..051c3930e808ed0dc8c565f2bfec94bf0baef708 100644 (file)
@@ -191,23 +191,20 @@ static int rxe_port_immutable(struct ib_device *dev, u8 port_num,
        return 0;
 }
 
-static struct ib_pd *rxe_alloc_pd(struct ib_device *dev,
-                                 struct ib_ucontext *context,
-                                 struct ib_udata *udata)
+static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
+                       struct ib_udata *udata)
 {
-       struct rxe_dev *rxe = to_rdev(dev);
-       struct rxe_pd *pd;
+       struct rxe_dev *rxe = to_rdev(ibpd->device);
+       struct rxe_pd *pd = to_rpd(ibpd);
 
-       pd = rxe_alloc(&rxe->pd_pool);
-       return pd ? &pd->ibpd : ERR_PTR(-ENOMEM);
+       return rxe_add_to_pool(&rxe->pd_pool, &pd->pelem);
 }
 
-static int rxe_dealloc_pd(struct ib_pd *ibpd)
+static void rxe_dealloc_pd(struct ib_pd *ibpd)
 {
        struct rxe_pd *pd = to_rpd(ibpd);
 
        rxe_drop_ref(pd);
-       return 0;
 }
 
 static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd,
@@ -1183,6 +1180,7 @@ static const struct ib_device_ops rxe_dev_ops = {
        .reg_user_mr = rxe_reg_user_mr,
        .req_notify_cq = rxe_req_notify_cq,
        .resize_cq = rxe_resize_cq,
+       INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd),
 };
 
 int rxe_register_device(struct rxe_dev *rxe)
index 74e04801d34db1643bc398719c56f54a5943f8f4..70839d3f55d941a30f1371331843ff6fc1f01d16 100644 (file)
@@ -66,8 +66,8 @@ struct rxe_ucontext {
 };
 
 struct rxe_pd {
+       struct ib_pd            ibpd;
        struct rxe_pool_entry   pelem;
-       struct ib_pd            ibpd;
 };
 
 struct rxe_ah {
index e29eae4aec84557a17db5c6c1f829de1a10c3336..854d7816787c9e33782e0f7682bdac6b09fd7c53 100644 (file)
@@ -2385,10 +2385,9 @@ struct ib_device_ops {
        int (*dealloc_ucontext)(struct ib_ucontext *context);
        int (*mmap)(struct ib_ucontext *context, struct vm_area_struct *vma);
        void (*disassociate_ucontext)(struct ib_ucontext *ibcontext);
-       struct ib_pd *(*alloc_pd)(struct ib_device *device,
-                                 struct ib_ucontext *context,
-                                 struct ib_udata *udata);
-       int (*dealloc_pd)(struct ib_pd *pd);
+       int (*alloc_pd)(struct ib_pd *pd, struct ib_ucontext *context,
+                       struct ib_udata *udata);
+       void (*dealloc_pd)(struct ib_pd *pd);
        struct ib_ah *(*create_ah)(struct ib_pd *pd,
                                   struct rdma_ah_attr *ah_attr, u32 flags,
                                   struct ib_udata *udata);
@@ -2530,6 +2529,8 @@ struct ib_device_ops {
         */
        int (*fill_res_entry)(struct sk_buff *msg,
                              struct rdma_restrack_entry *entry);
+
+       DECLARE_RDMA_OBJ_SIZE(ib_pd);
 };
 
 struct ib_device {