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

Noralf Trønnes noralf at tronnes.org
Mon Apr 16 15:58:23 UTC 2018


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).

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);


Noralf.



More information about the dri-devel mailing list