@@ -390,7 +390,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
return uobj_alloc_commit(uobj, in_len);
err_copy:
- ib_dealloc_pd(pd);
+ ib_dealloc_pd_user(pd, &udata);
err:
uobj_alloc_abort(uobj);
@@ -181,13 +181,17 @@ static int uverbs_free_pd(struct ib_uobject *uobject,
enum rdma_remove_reason why)
{
struct ib_pd *pd = uobject->object;
+ struct ib_udata udata = {0};
int ret;
ret = ib_destroy_usecnt(&pd->usecnt, why, uobject);
if (ret)
return ret;
- ib_dealloc_pd((struct ib_pd *)uobject->object);
+ ib_uverbs_init_udata_buf_or_null(&udata, NULL, NULL, 0, 0,
+ uobject->context);
+
+ ib_dealloc_pd_user((struct ib_pd *)uobject->object, &udata);
return 0;
}
@@ -296,14 +296,15 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
EXPORT_SYMBOL(__ib_alloc_pd);
/**
- * ib_dealloc_pd - Deallocates a protection domain.
+ * ib_dealloc_pd_user - Deallocates a protection domain.
* @pd: The protection domain to deallocate.
+ * @udata: User data (if any)
*
* It is an error to call this function while any resources in the pd still
* exist. The caller is responsible to synchronously destroy them and
* guarantee no new allocations will happen.
*/
-void ib_dealloc_pd(struct ib_pd *pd)
+void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
{
int ret;
@@ -320,9 +321,26 @@ void ib_dealloc_pd(struct ib_pd *pd)
rdma_restrack_del(&pd->res);
/* Making delalloc_pd a void return is a WIP, no driver should return
an error here. */
- ret = pd->device->dealloc_pd(pd);
+ ret = pd->device->dealloc_pd(pd, udata);
WARN_ONCE(ret, "Infiniband HW driver failed dealloc_pd");
}
+EXPORT_SYMBOL(ib_dealloc_pd_user);
+
+/**
+ * ib_dealloc_pd - Deallocates a protection domain.
+ * @pd: The protection domain to deallocate.
+ *
+ * It is an error to call this function while any resources in the pd still
+ * exist. The caller is responsible to synchronously destroy them and
+ * guarantee no new allocations will happen.
+ *
+ * NOTE: Never call this function from uverbs!
+ */
+void ib_dealloc_pd(struct ib_pd *pd)
+{
+ WARN_ON(rdma_is_user_pd(pd));
+ ib_dealloc_pd_user(pd, NULL);
+}
EXPORT_SYMBOL(ib_dealloc_pd);
/* Address handles */
@@ -563,7 +563,7 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd)
}
/* Protection Domains */
-int bnxt_re_dealloc_pd(struct ib_pd *ib_pd)
+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;
@@ -166,7 +166,7 @@ enum rdma_link_layer bnxt_re_get_link_layer(struct ib_device *ibdev,
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_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
struct ib_ah *bnxt_re_create_ah(struct ib_pd *pd,
struct rdma_ah_attr *ah_attr,
struct ib_udata *udata);
@@ -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 int iwch_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
{
struct iwch_dev *rhp;
struct iwch_pd *php;
@@ -407,7 +407,7 @@ static struct ib_pd *iwch_allocate_pd(struct ib_device *ibdev,
struct iwch_alloc_pd_resp resp = {.pdid = php->pdid};
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
- iwch_deallocate_pd(&php->ibpd);
+ iwch_deallocate_pd(&php->ibpd, udata);
return ERR_PTR(-EFAULT);
}
}
@@ -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 int c4iw_deallocate_pd(struct ib_pd *pd, struct ib_udata *udata)
{
struct c4iw_dev *rhp;
struct c4iw_pd *php;
@@ -249,7 +249,7 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
struct c4iw_alloc_pd_resp uresp = {.pdid = php->pdid};
if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
- c4iw_deallocate_pd(&php->ibpd);
+ c4iw_deallocate_pd(&php->ibpd, udata);
return ERR_PTR(-EFAULT);
}
}
@@ -373,7 +373,7 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
* i40iw_dealloc_pd - deallocate pd
* @ibpd: ptr of pd to be deallocated
*/
-static int i40iw_dealloc_pd(struct ib_pd *ibpd)
+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);
@@ -1210,7 +1210,7 @@ static struct ib_pd *mlx4_ib_alloc_pd(struct ib_device *ibdev,
return &pd->ibpd;
}
-static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
+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);
kfree(pd);
@@ -2289,7 +2289,7 @@ static struct ib_pd *mlx5_ib_alloc_pd(struct ib_device *ibdev,
return &pd->ibpd;
}
-static int mlx5_ib_dealloc_pd(struct ib_pd *pd)
+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);
@@ -4670,7 +4670,7 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
error2:
mlx5_ib_destroy_cq(devr->c0);
error1:
- mlx5_ib_dealloc_pd(devr->p0);
+ mlx5_ib_dealloc_pd(devr->p0, NULL);
error0:
return ret;
}
@@ -4686,7 +4686,7 @@ static void destroy_dev_resources(struct mlx5_ib_resources *devr)
mlx5_ib_dealloc_xrcd(devr->x0);
mlx5_ib_dealloc_xrcd(devr->x1);
mlx5_ib_destroy_cq(devr->c0);
- mlx5_ib_dealloc_pd(devr->p0);
+ mlx5_ib_dealloc_pd(devr->p0, NULL);
/* Make sure no change P_Key work items are still executing */
for (port = 0; port < dev->num_ports; ++port)
@@ -402,7 +402,7 @@ static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
return &pd->ibpd;
}
-static int mthca_dealloc_pd(struct ib_pd *pd)
+static int mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
{
mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
kfree(pd);
@@ -725,7 +725,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev,
/**
* nes_dealloc_pd
*/
-static int nes_dealloc_pd(struct ib_pd *ibpd)
+static int nes_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
{
struct nes_ucontext *nesucontext;
struct nes_pd *nespd = to_nespd(ibpd);
@@ -714,7 +714,7 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev,
return ERR_PTR(status);
}
-int ocrdma_dealloc_pd(struct ib_pd *ibpd)
+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);
@@ -72,7 +72,7 @@ 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_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev,
const struct ib_cq_init_attr *attr,
@@ -511,7 +511,7 @@ struct ib_pd *qedr_alloc_pd(struct ib_device *ibdev,
return ERR_PTR(rc);
}
-int qedr_dealloc_pd(struct ib_pd *ibpd)
+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);
@@ -49,7 +49,7 @@ 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_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
struct ib_cq *qedr_create_cq(struct ib_device *ibdev,
const struct ib_cq_init_attr *attr,
@@ -477,7 +477,7 @@ struct ib_pd *usnic_ib_alloc_pd(struct ib_device *ibdev,
return &pd->ibpd;
}
-int usnic_ib_dealloc_pd(struct ib_pd *pd)
+int usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
{
usnic_info("freeing domain 0x%p\n", pd);
@@ -54,7 +54,7 @@ int usnic_ib_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
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_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);
@@ -484,7 +484,7 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
if (ib_copy_to_udata(udata, &pd_resp, sizeof(pd_resp))) {
dev_warn(&dev->pdev->dev,
"failed to copy back protection domain\n");
- pvrdma_dealloc_pd(&pd->ibpd);
+ pvrdma_dealloc_pd(&pd->ibpd, udata);
return ERR_PTR(-EFAULT);
}
}
@@ -505,7 +505,7 @@ struct ib_pd *pvrdma_alloc_pd(struct ib_device *ibdev,
*
* @return: 0 on success, otherwise errno.
*/
-int pvrdma_dealloc_pd(struct ib_pd *pd)
+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;
@@ -402,7 +402,7 @@ 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_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,
@@ -214,7 +214,7 @@ static struct ib_pd *rxe_alloc_pd(struct ib_device *dev,
return pd ? &pd->ibpd : ERR_PTR(-ENOMEM);
}
-static int rxe_dealloc_pd(struct ib_pd *ibpd)
+static int rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
{
struct rxe_pd *pd = to_rpd(ibpd);
@@ -2366,7 +2366,8 @@ struct ib_device {
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 (*dealloc_pd)(struct ib_pd *pd,
+ struct ib_udata *udata);
struct ib_ah * (*create_ah)(struct ib_pd *pd,
struct rdma_ah_attr *ah_attr,
struct ib_udata *udata);
@@ -3158,6 +3159,7 @@ struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags,
const char *caller);
#define ib_alloc_pd(device, flags) \
__ib_alloc_pd((device), (flags), KBUILD_MODNAME)
+void ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata);
void ib_dealloc_pd(struct ib_pd *pd);
/**
prepare the code for shared ib_x model. ib_ucontext is currently taken from ib_pd uobject pointer. having single uobject pointer in ib_x object is not aligned with future shared ib_x model. in future shared ib_x model each ib_x object can belong to 1 or more ib_uobject. the current ib_context that is used should thus come from uverbs. convey the ib_ucontext via ib_udata that is used in (almost) all the places where ib_ucontext is needed. Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com> --- drivers/infiniband/core/uverbs_cmd.c | 2 +- drivers/infiniband/core/uverbs_std_types.c | 6 ++++- drivers/infiniband/core/verbs.c | 24 ++++++++++++++++--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 +- drivers/infiniband/hw/bnxt_re/ib_verbs.h | 2 +- drivers/infiniband/hw/cxgb3/iwch_provider.c | 4 ++-- drivers/infiniband/hw/cxgb4/provider.c | 4 ++-- drivers/infiniband/hw/i40iw/i40iw_verbs.c | 2 +- drivers/infiniband/hw/mlx4/main.c | 2 +- drivers/infiniband/hw/mlx5/main.c | 6 ++--- drivers/infiniband/hw/mthca/mthca_provider.c | 2 +- drivers/infiniband/hw/nes/nes_verbs.c | 2 +- drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +- drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | 2 +- drivers/infiniband/hw/qedr/verbs.c | 2 +- drivers/infiniband/hw/qedr/verbs.h | 2 +- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 2 +- drivers/infiniband/hw/usnic/usnic_ib_verbs.h | 2 +- .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.c | 4 ++-- .../infiniband/hw/vmw_pvrdma/pvrdma_verbs.h | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.c | 2 +- include/rdma/ib_verbs.h | 4 +++- 22 files changed, 53 insertions(+), 29 deletions(-)