Re: [PATCH for-next 1/1] IB/{hw,sw}: remove 'uobject->context' dependency in object creation APIs

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

 



On Thu, Jan 17, 2019 at 01:38:20PM -0700, Jason Gunthorpe wrote:
> On Thu, Jan 17, 2019 at 09:11:12PM +0200, Shamir Rabinovitch wrote:
> > Now when we have the udata passed to all the ib_xxx object creation APIs
> > and the additional function 'rdma_get_ucontext' to get the ib_ucontext
> > from ib_udata stored in uverbs_attr_bundle, we can finally start to remove
> > the dependency of the drivers in the ib_xxx->uobject->context.
> > 

[...]

> 
> Hurm.. I think if you are going to use this API so widely then we need
> to arrange for it to not fail. If udata is not null, and we are in a
> driver callback with an object, then the ucontext should be guaranteed
> available.
> 
> Otherwise we have weird cases where udata and !rdma_get_ucontext() can
> be true, which is really horrible to reason about..
> 
> The way to do this is to have the core code places that have a uobject
> copy the ucontext from the uobject into the udata, I think I mentioned
> this before, and it is a fixme in the code..
> 
> For instance something like this would take care of things for the
> ioctl path:
> 
> diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
> index 8c81ff69805276..9e9240645fbe9b 100644
> --- a/drivers/infiniband/core/uverbs_ioctl.c
> +++ b/drivers/infiniband/core/uverbs_ioctl.c
> @@ -198,6 +198,7 @@ static int uverbs_process_idrs_array(struct bundle_priv *pbundle,
>                         ret = PTR_ERR(attr->uobjects[i]);
>                         break;
>                 }
> +               pbundle->bundle.ucontext = attr->ubojects[i].ucontext;
>         }
>  
>         attr->len = i;
> @@ -316,6 +317,7 @@ static int uverbs_process_attr(struct bundle_priv *pbundle,
>                 if (IS_ERR(o_attr->uobject))
>                         return PTR_ERR(o_attr->uobject);
>                 __set_bit(attr_bkey, pbundle->uobj_finalize);
> +               pbundle->bundle.ucontext = o_attr->uoboject.ucontext;
>  
>                 if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
>                         unsigned int uattr_idx = uattr - pbundle->uattrs;
> 
> And the cmd path needs some editing of its alloc/get macros


OK. If I take ib_uverbs_alloc_pd as example I see:

ib_uverbs_write -> ib_uverbs_alloc_pd -> uobj_alloc -> __uobj_alloc ->
rdma_alloc_begin_uobject -> alloc_begin_idr_uobject -> alloc_uobj -> 
ib_uverbs_get_ucontext_file

So it seems that the best place to pass the ib_ucontext to
uverbs_attr_bundle is in __uobj_alloc in this call chain.



I have this question about ib_ucontext in ib_uobject:

I see this comment above ib_uverbs_get_ucontext_file:
"
* Must be called with the ufile->device->disassociate_srcu held, and the lock
* must be held until use of the ucontext is finished.
"

Surly, when ib_uobject has pointer to ib_ucontext the above lock is not held for all
the duration.

What prevent the use of the ib_ucontext from ib_uobject after device has been
disassociated ?

Is it the fact that ib_uobject are only accessed via ib_uverbs_write for commands
which hold the disassociate_srcu and that uverbs_disassociate_api_pre disable the 
commands for uverbs_api for that ib_uverbs_device ? 

Are there any paths that touch ib_uobject but not with in ib_uverbs_write protection ?

Is this related to the point that you do not want to assume ib_udata (&context) in the
ib_xxx destroy path ? 

If so, will it be acceptable to move the ib_xxx driver related data hanged on the ib_ucontext 
to the ib_xxx driver object and prevent sharing of this specific object in this specific 
driver to remove the dependency in the destroy path in the ib_ucontext ?

Will it be acceptable to have each driver to decide what objects are shareable and what
are not (those with data hanged on ib_ucontext are not shareable)?


> > +	context = rdma_get_ucontext(udata);
> > +	if (IS_ERR(context))
> > +		return PTR_ERR(context);
> 
> Like here, this is getting really long..
> 
> And this should probably follow the pattern of the new
> rdma_device_to_drv_device() to make it simpler..
> 
> Just add something like this at the start of functions:
> 
>    struct bnxt_re_ucontext *cntx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
> 
> returns NULL if kernel mode.
> 
> And then use 'if (cntx)' instead of 'if (udata)' in that function to
> test for user/kernel mode..
> 
> Jason

OK.



[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