Re: [PATCH rdma-next] RDMA: Handle ucontext allocations by IB/core

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 04, 2019 at 03:56:21PM +0200, Leon Romanovsky wrote:
> diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
> index 0aeb53ef7869..a48bb388160d 100644
> +++ b/drivers/infiniband/core/uverbs_cmd.c
> @@ -224,13 +224,19 @@ 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;
>  	}
>  
> +	rdma_rt_set_type(&ucontext->res, RDMA_RESTRACK_CTX);
>  	ucontext->device = ib_dev;
> +
> +	ret = ib_dev->ops.alloc_ucontext(ucontext, &attrs->driver_udata);
> +	if (ret)
> +		goto err_free;
> +
>  	ucontext->cg_obj = cg_obj;
>  	/* ufile is required when some objects are released */
>  	ucontext->ufile = file;
> @@ -262,7 +268,6 @@ static int ib_uverbs_get_context(struct uverbs_attr_bundle *attrs)
>  
>  	fd_install(resp.async_fd, filp);
>  
> -	rdma_rt_set_type(&ucontext->res, RDMA_RESTRACK_CTX);
>  	rdma_restrack_uadd(&ucontext->res);
>  
>  	/*
> @@ -283,7 +288,7 @@ static int ib_uverbs_get_context(struct uverbs_attr_bundle *attrs)
>  	put_unused_fd(resp.async_fd);
>  
>  err_free:
> -	ib_dev->ops.dealloc_ucontext(ucontext);
> +	kfree(ucontext);

This error unwind isn't right any more. 

Re-organize it to have the driver call at the end when failure still
works on the existing goto unwind

> @@ -565,6 +556,7 @@ static const struct ib_device_ops c4iw_dev_ops = {
>  	.reg_user_mr = c4iw_reg_user_mr,
>  	.req_notify_cq = c4iw_arm_cq,
>  	INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd),
> +	INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext),
>  };
>  
>  void c4iw_register_device(struct work_struct *work)
> diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
> index 0fe87b9c1e10..5da85f7679d8 100644
> +++ b/drivers/infiniband/hw/cxgb4/qp.c
> @@ -2338,7 +2338,6 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
>  			insert_mmap(ucontext, ma_sync_key_mm);
>  		}
>  
> -		c4iw_get_ucontext(ucontext);
>  		qhp->ucontext = ucontext;

Why? Looks wrong...

Actually this whole cxgb4 stuff looks very peculiar - I don't see how
we can safely move the kfree out of its kref release and into the core
code and be sure it will still work...

Arguably drivers should not be refcounting these structs though - I
wonder if the ref counting could be deleted?

Steve? Is there some reason cxgb4 is the only driver trying to stick a
refcount on the ucontext? 

ucontext deletion means that every object contained in the ucontext
has been deleted, the core code guarentees this.

If there is some async work someplace then generally it should be
flushed/canceled during ucontext delete, not managed via kref...

ie there is no reason for that mmap stuff to be under the kref
release, c4iw_mmap will not be called once the core destroyes the
ucontext. 

Fixing this needs another patch..

>  /**
>   * i40iw_dealloc_ucontext - deallocate the user context data structure
>   * @context: user context created during alloc
>   */
> -static int i40iw_dealloc_ucontext(struct ib_ucontext *context)
> +static void i40iw_dealloc_ucontext(struct ib_ucontext *context)
>  {
>  	struct i40iw_ucontext *ucontext = to_ucontext(context);
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
> -	if (!list_empty(&ucontext->cq_reg_mem_list)) {
> -		spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);
> -		return -EBUSY;
> -	}
> -	spin_unlock_irqrestore(&ucontext->cq_reg_mem_list_lock, flags);
> -	spin_lock_irqsave(&ucontext->qp_reg_mem_list_lock, flags);
> -	if (!list_empty(&ucontext->qp_reg_mem_list)) {
> -		spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
> -		return -EBUSY;
> -	}
> -	spin_unlock_irqrestore(&ucontext->qp_reg_mem_list_lock, flags);
>  
> -	kfree(ucontext);
> -	return 0;
> +	/*
> +	 * dealloc called before all MRs QPs were freed,
> +	 * no need to grab XXX_reg_mem_list_lock locks,
> +	 * it is too lat and the warning below symbol of bug
> +	 * in th driver.
> +	 */

various spelling errors

> diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
> index e02a5662dc20..114a9b59fefd 100644
> +++ b/drivers/infiniband/hw/nes/nes_verbs.h
> @@ -59,7 +59,6 @@ struct nes_ucontext {
>  	struct list_head   cq_reg_mem_list;
>  	struct list_head   qp_reg_mem_list;
>  	u32                mcrqf;
> -	atomic_t	   usecnt;

Lets have this in its own patch please

> diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
> index f44220f72e05..196d7a6e4c8c 100644
> +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
> @@ -306,41 +306,33 @@ int pvrdma_modify_port(struct ib_device *ibdev, u8 port, int mask,
>  
>  /**
>   * pvrdma_alloc_ucontext - allocate ucontext
> - * @ibdev: the IB device
> + * @uctx: the uverbs countext
>   * @udata: user data
>   *
> - * @return: the ib_ucontext pointer on success, otherwise errno.
> + * @return:  zero on success, otherwise errno.
>   */
> -struct ib_ucontext *pvrdma_alloc_ucontext(struct ib_device *ibdev,
> -					  struct ib_udata *udata)
> +int vrdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)

Wrong name

Jason



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux