[Intel-gfx] [RFC v4 19/25] drm/client: Finish the in-kernel client API

Daniel Vetter daniel at ffwll.ch
Tue Apr 17 08:08:03 UTC 2018


On Mon, Apr 16, 2018 at 05:58:23PM +0200, Noralf Trønnes wrote:
> 
> Den 16.04.2018 10.27, skrev Daniel Vetter:
> > On Sat, Apr 14, 2018 at 01:53:12PM +0200, Noralf Trønnes wrote:
> > > The modesetting code is already present, this adds the rest of the API.
> > Mentioning the TODO in the commit message would be good. Helps readers
> > like me who have an attention span measured in seconds :-)
> > 
> > Just commenting on the create_buffer leak here
> > 
> > > +static struct drm_client_buffer *
> > > +drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
> > > +{
> > > +	struct drm_mode_create_dumb dumb_args = { };
> > > +	struct drm_prime_handle prime_args = { };
> > > +	struct drm_client_buffer *buffer;
> > > +	struct dma_buf *dma_buf;
> > > +	void *vaddr;
> > > +	int ret;
> > > +
> > > +	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
> > > +	if (!buffer)
> > > +		return ERR_PTR(-ENOMEM);
> > > +
> > > +	buffer->client = client;
> > > +	buffer->width = width;
> > > +	buffer->height = height;
> > > +	buffer->format = format;
> > > +
> > > +	dumb_args.width = buffer->width;
> > > +	dumb_args.height = buffer->height;
> > > +	dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
> > > +	ret = drm_mode_create_dumb(client->dev, &dumb_args, client->file);
> > > +	if (ret)
> > > +		goto err_free;
> > > +
> > > +	buffer->handle = dumb_args.handle;
> > > +	buffer->pitch = dumb_args.pitch;
> > > +	buffer->size = dumb_args.size;
> > > +
> > > +	prime_args.handle = dumb_args.handle;
> > > +	ret = drm_prime_handle_to_fd(client->dev, &prime_args, client->file);
> > > +	if (ret)
> > > +		goto err_delete;
> > > +
> > > +	dma_buf = dma_buf_get(prime_args.fd);
> > > +	if (IS_ERR(dma_buf)) {
> > > +		ret = PTR_ERR(dma_buf);
> > > +		goto err_delete;
> > > +	}
> > > +
> > > +	/*
> > > +	 * If called from a worker the dmabuf fd isn't closed and the ref
> > > +	 * doesn't drop to zero on free.
> > > +	 * If I use __close_fd() it's all fine, but that function is not exported.
> > > +	 *
> > > +	 * How do I get rid of this fd when in a worker/kernel thread?
> > > +	 * The fd isn't used beyond this function.
> > > +	 */
> > > +//	WARN_ON(__close_fd(current->files, prime_args.fd));
> > Hm, this isn't 100% what I had in mind as the sequence for generic buffer
> > creation. Pseudo-code:
> > 
> > 	ret = drm_mode_create_dumb(client->dev, &dumb_args, client->file);
> > 	if (ret)
> > 		goto err_free;
> > 	
> > 	gem_bo = drm_gem_object_lookup(client->file, dumb_args.handle);
> > 
> > gives you _really_ directly the underlying gem_bo. Of course this doesn't
> > work for non-gem based driver, but reality is that (almost) all of them
> > are. And we will not accept any new drivers which aren't gem based. So
> > ignoring vmwgfx for this drm_client work is imo perfectly fine. We should
> > ofc keep the option in the fb helpers to use non-gem buffers (so that
> > vmwgfx could switch over from their own in-driver fbdev helpers). All we
> > need for that is to keep the fb_probe callback.
> > 
> > Was there any other reason than vmwgfx for using prime buffers instead of
> > just directly using gem?
> 
> The reason for using a prime buffer is that it gives me easy access to a
> dma_buf which I use to get the virtual address (dma_buf_vmap) and for
> mmap (dma_buf_mmap).

Ah yes, I missed that.

Wrt mmap, not sure we should use the dma-buf mmap or the dumb mmap. I
guess in the end it wont matter much really.

> 
> Would this stripped down version of drm_gem_prime_handle_to_fd() work?
> 
> struct dma_buf *drm_gem_to_dmabuf(struct drm_gem_object *obj)
> {
>     struct dma_buf *dmabuf;
> 
>     mutex_lock(&obj->dev->object_name_lock);
>     /* re-export the original imported object */
>     if (obj->import_attach) {
>         dmabuf = obj->import_attach->dmabuf;
>         get_dma_buf(dmabuf);
>         goto out;
>     }
> 
>     if (obj->dma_buf) {
>         dmabuf = obj->dma_buf;
>         get_dma_buf(dmabuf);
>         goto out;
>     }
> 
>     dmabuf = export_and_register_object(obj->dev, obj, 0);
> out:
>     mutex_unlock(&obj->dev->object_name_lock);
> 
>     return dmabuf;
> }
> 
> Now I could do this:
> 
>     ret = drm_mode_create_dumb(dev, &dumb_args, file);
> 
>     obj = drm_gem_object_lookup(file, dumb_args.handle);
> 
>     dmabuf = drm_gem_to_dmabuf(obj);
> 
>     vaddr = dma_buf_vmap(dmabuf);

Nah, if we need the dma-buf anyway, I'd try to go directly from the handle
to the dma-buf. So roughly:

	ret = drm_mode_create_dumb(dev, &dumb_args, file);
	
	dma_buf = drm_gem_prime_handle_to_dmabuf(file, dumb_args.handle);

See my reply to the ioctl wrapper patch for details.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


More information about the Intel-gfx mailing list