Commit a2a074ef authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe
Browse files

RDMA: Handle ucontext allocations by IB/core



Following the PD conversion patch, do the same for ucontext allocations.

Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent afc1990e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1832,6 +1832,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
	SET_DEVICE_OP(dev_ops, unmap_fmr);

	SET_OBJ_SIZE(dev_ops, ib_pd);
	SET_OBJ_SIZE(dev_ops, ib_ucontext);
}
EXPORT_SYMBOL(ib_set_device_ops);

+2 −7
Original line number Diff line number Diff line
@@ -844,7 +844,6 @@ static void ufile_destroy_ucontext(struct ib_uverbs_file *ufile,
{
	struct ib_ucontext *ucontext = ufile->ucontext;
	struct ib_device *ib_dev = ucontext->device;
	int ret;

	/*
	 * If we are closing the FD then the user mmap VMAs must have
@@ -862,12 +861,8 @@ static void ufile_destroy_ucontext(struct ib_uverbs_file *ufile,

	rdma_restrack_del(&ucontext->res);

	/*
	 * FIXME: Drivers are not permitted to fail dealloc_ucontext, remove
	 * the error return.
	 */
	ret = ib_dev->ops.dealloc_ucontext(ucontext);
	WARN_ON(ret);
	ib_dev->ops.dealloc_ucontext(ucontext);
	kfree(ucontext);

	ufile->ucontext = NULL;
}
+14 −10
Original line number Diff line number Diff line
@@ -224,12 +224,13 @@ static int ib_uverbs_get_context(struct uverbs_attr_bundle *attrs)
	if (ret)
		goto err;

	ucontext = ib_dev->ops.alloc_ucontext(ib_dev, &attrs->driver_udata);
	if (IS_ERR(ucontext)) {
		ret = PTR_ERR(ucontext);
	ucontext = rdma_zalloc_drv_obj(ib_dev, ib_ucontext);
	if (!ucontext) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	ucontext->res.type = RDMA_RESTRACK_CTX;
	ucontext->device = ib_dev;
	ucontext->cg_obj = cg_obj;
	/* ufile is required when some objects are released */
@@ -240,10 +241,6 @@ static int ib_uverbs_get_context(struct uverbs_attr_bundle *attrs)

	mutex_init(&ucontext->per_mm_list_lock);
	INIT_LIST_HEAD(&ucontext->per_mm_list);
	if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
		ucontext->invalidate_range = NULL;

	resp.num_comp_vectors = file->device->num_comp_vectors;

	ret = get_unused_fd_flags(O_CLOEXEC);
	if (ret < 0)
@@ -256,15 +253,22 @@ static int ib_uverbs_get_context(struct uverbs_attr_bundle *attrs)
		goto err_fd;
	}

	resp.num_comp_vectors = file->device->num_comp_vectors;

	ret = uverbs_response(attrs, &resp, sizeof(resp));
	if (ret)
		goto err_file;

	fd_install(resp.async_fd, filp);
	ret = ib_dev->ops.alloc_ucontext(ucontext, &attrs->driver_udata);
	if (ret)
		goto err_file;
	if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_ON_DEMAND_PAGING))
		ucontext->invalidate_range = NULL;

	ucontext->res.type = RDMA_RESTRACK_CTX;
	rdma_restrack_uadd(&ucontext->res);

	fd_install(resp.async_fd, filp);

	/*
	 * Make sure that ib_uverbs_get_ucontext() sees the pointer update
	 * only after all writes to setup the ucontext have completed
@@ -283,7 +287,7 @@ err_fd:
	put_unused_fd(resp.async_fd);

err_free:
	ib_dev->ops.dealloc_ucontext(ucontext);
	kfree(ucontext);

err_alloc:
	ib_rdmacg_uncharge(&cg_obj, ib_dev, RDMACG_RESOURCE_HCA_HANDLE);
+10 −22
Original line number Diff line number Diff line
@@ -3671,13 +3671,14 @@ free_mr:
	return ERR_PTR(rc);
}

struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
					   struct ib_udata *udata)
int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
{
	struct ib_device *ibdev = ctx->device;
	struct bnxt_re_ucontext *uctx =
		container_of(ctx, struct bnxt_re_ucontext, ib_uctx);
	struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
	struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
	struct bnxt_re_uctx_resp resp;
	struct bnxt_re_ucontext *uctx;
	u32 chip_met_rev_num = 0;
	int rc;

@@ -3687,13 +3688,9 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
	if (ibdev->uverbs_abi_ver != BNXT_RE_ABI_VERSION) {
		dev_dbg(rdev_to_dev(rdev), " is different from the device %d ",
			BNXT_RE_ABI_VERSION);
		return ERR_PTR(-EPERM);
		return -EPERM;
	}

	uctx = kzalloc(sizeof(*uctx), GFP_KERNEL);
	if (!uctx)
		return ERR_PTR(-ENOMEM);

	uctx->rdev = rdev;

	uctx->shpg = (void *)__get_free_page(GFP_KERNEL);
@@ -3727,23 +3724,21 @@ struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
		goto cfail;
	}

	return &uctx->ib_uctx;
	return 0;
cfail:
	free_page((unsigned long)uctx->shpg);
	uctx->shpg = NULL;
fail:
	kfree(uctx);
	return ERR_PTR(rc);
	return rc;
}

int bnxt_re_dealloc_ucontext(struct ib_ucontext *ib_uctx)
void bnxt_re_dealloc_ucontext(struct ib_ucontext *ib_uctx)
{
	struct bnxt_re_ucontext *uctx = container_of(ib_uctx,
						   struct bnxt_re_ucontext,
						   ib_uctx);

	struct bnxt_re_dev *rdev = uctx->rdev;
	int rc = 0;

	if (uctx->shpg)
		free_page((unsigned long)uctx->shpg);
@@ -3752,17 +3747,10 @@ int bnxt_re_dealloc_ucontext(struct ib_ucontext *ib_uctx)
		/* Free DPI only if this is the first PD allocated by the
		 * application and mark the context dpi as NULL
		 */
		rc = bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
					    &rdev->qplib_res.dpi_tbl,
					    &uctx->dpi);
		if (rc)
			dev_err(rdev_to_dev(rdev), "Deallocate HW DPI failed!");
			/* Don't fail, continue*/
		bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
				       &rdev->qplib_res.dpi_tbl, &uctx->dpi);
		uctx->dpi.dbr = NULL;
	}

	kfree(uctx);
	return 0;
}

/* Helper function to mmap the virtual memory from user app */
+3 −4
Original line number Diff line number Diff line
@@ -135,8 +135,8 @@ struct bnxt_re_mw {
};

struct bnxt_re_ucontext {
	struct bnxt_re_dev	*rdev;
	struct ib_ucontext      ib_uctx;
	struct bnxt_re_dev	*rdev;
	struct bnxt_qplib_dpi	dpi;
	void			*shpg;
	spinlock_t		sh_lock;	/* protect shpg */
@@ -215,9 +215,8 @@ int bnxt_re_dealloc_mw(struct ib_mw *mw);
struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
				  u64 virt_addr, int mr_access_flags,
				  struct ib_udata *udata);
struct ib_ucontext *bnxt_re_alloc_ucontext(struct ib_device *ibdev,
					   struct ib_udata *udata);
int bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata);
void bnxt_re_dealloc_ucontext(struct ib_ucontext *context);
int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);

unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
Loading