[Intel-gfx] [PATCH v2 00/12] drm: Add generic fbdev emulation
Noralf Trønnes
noralf at tronnes.org
Wed Jun 20 15:28:10 UTC 2018
Den 20.06.2018 15.52, skrev Noralf Trønnes:
>
> Den 20.06.2018 11.34, skrev Daniel Vetter:
>> On Mon, Jun 18, 2018 at 04:17:27PM +0200, Noralf Trønnes wrote:
>>> This patchset adds generic fbdev emulation for drivers that supports
>>> GEM
>>> based dumb buffers which support .gem_prime_vmap and gem_prime_mmap. An
>>> API is begun to support in-kernel clients in general.
>>>
>>> Notable changes since version 1:
>>>
>>> - Rework client unregister code. I've used reference counting to manage
>>> the fact that both the client itself and the driver through
>>> drm_dev_unregister() can release the client. The client is now
>>> released
>>> using drm_client_put() instead of drm_client_free().
>> I started reviewing the reworked client register/unregister stuff,
>> and it
>> looks good, except this kref stuff here for clients. I don't understand
>> why you need this - as long as removal from dev->clientlist is properly
>> protected by the mutex, I don't see how both the client and the
>> device can
>> release the client at the same time. Of course this means that both the
>> device-trigger unregister and the client-triggered unregister must first
>> grab the mutex, remove the client from the list, and only if that was
>> done
>> succesfully, clean up the client. If the client is already removed from
>> the list (i.e. list_empty() is true) then you need to bail out to avoid
>> double-freeing.
>
> I just suck at this :/
>
> Use case:
> Unloading client module at the same time as the device is unplugged.
>
> The client module calls drm_client_release():
>
> void drm_client_release(struct drm_client_dev *client)
> {
> struct drm_device *dev = client->dev;
>
> mutex_lock(&dev->clientlist_mutex);
> list_del(&client->list);
> drm_client_close(client);
> mutex_unlock(&dev->clientlist_mutex);
> drm_dev_put(dev);
> }
>
>
> drm_device_unregister() calls drm_client_dev_unregister():
>
> void drm_client_dev_unregister(struct drm_device *dev)
> {
> struct drm_client_dev *client;
>
> mutex_lock(&dev->clientlist_mutex);
> list_for_each_entry(client, &dev->clientlist, list) {
> if (client->funcs && client->funcs->unregister)
> client->funcs->unregister(client);
> else
> drm_client_release(client);
> }
> mutex_unlock(&dev->clientlist_mutex);
> }
>
>
> How do I do this without deadlocking and without operating on a
> drm_client_dev structure that has been freed in the other codepath?
>
There's one more quirk that I forgot:
If fbdev can't release the client on .unregister due to open fd's, the
list entry should be removed but releasing resources is deferred to
the last fd being closed.
Noralf.
>
> Noralf.
>
>> I don't think there's a need to use a kref here. And kref has the tricky
>> issue that you tempt everyone into constructing references loops between
>> drm_device and drm_client (which require lots of jumping through
>> hoops in
>> your v1 to make sure you can break those reference loops).
>>
>>> - fbdev: Use a shadow buffer for framebuffers that have a dirty
>>> callback. This makes the fbdev client truly generic and useable
>>> for all
>>> drivers. There's a blitting penalty, but this is generic
>>> emulation after
>>> all. The reason for needing a shadow buffer is that deferred I/O
>>> only
>>> works with kmalloc/vmalloc buffers and not with shmem buffers
>>> (page->lru/mapping).
>> Yeah I think that's the only feasible option. Everyone who cares more
>> about fbdev performance can keep their driver-specific code. And for
>> other
>> drm_client users this shouldn't be a problem, since they know how to use
>> dirty and flipping between multiple buffers to drive kms as it was
>> designed. The issue really only exists for fbdev's assumption of a
>> direct
>> mmap of a dumb framebuffer, encoded into the uapi.
>>
>>> - Let tinydrm use the full fbdev client
>> \o/
>>
>> Cheers, Daniel
>>> Noralf.
>>>
>>> Changes since version 1:
>>> - Make it possible to embed struct drm_client_dev and drop the private
>>> pointer
>>> - Use kref reference counting to control client release since both the
>>> client and the driver can release.
>>> - Add comment about using dma-buf as a possibility with some rework
>>> - Move buffer NULL check to drm_client_framebuffer_delete()
>>> - Move client name to struct drm_client_dev
>>> - Move up drm_dev_get/put calls to make them more visible
>>> - Move drm_client_dev.list definition to later patch that makes use
>>> of it
>>>
>>> - Embed drm_client at the beginning of drm_fb_helper to avoid a fragile
>>> transitional kfree hack in drm_client_release()
>>> - Set owner in drm_fbdev_fb_ops
>>> - Add kerneldoc to drm_fb_helper_generic_probe()
>>>
>>> - Remove unused functions
>>> - Change name drm_client_funcs.lastclose -> .restore
>>> - Change name drm_client_funcs.remove -> .unregister
>>> - Rework unregister code
>>>
>>> - tinydrm: Use drm_fbdev_generic_setup() and remove
>>> drm_fb_cma_fbdev_init_with_funcs()
>>>
>>> David Herrmann (1):
>>> drm: provide management functions for drm_file
>>>
>>> Noralf Trønnes (11):
>>> drm/file: Don't set master on in-kernel clients
>>> drm: Make ioctls available for in-kernel clients
>>> drm: Begin an API for in-kernel clients
>>> drm/fb-helper: Add generic fbdev emulation .fb_probe function
>>> drm/pl111: Set .gem_prime_vmap and .gem_prime_mmap
>>> drm/cma-helper: Use the generic fbdev emulation
>>> drm/client: Add client callbacks
>>> drm/debugfs: Add internal client debugfs file
>>> drm/fb-helper: Finish the generic fbdev emulation
>>> drm/tinydrm: Use drm_fbdev_generic_setup()
>>> drm/cma-helper: Remove drm_fb_cma_fbdev_init_with_funcs()
>>>
>>> Documentation/gpu/drm-client.rst | 12 +
>>> Documentation/gpu/index.rst | 1 +
>>> drivers/gpu/drm/Makefile | 2 +-
>>> drivers/gpu/drm/drm_client.c | 435
>>> ++++++++++++++++++++++++++++
>>> drivers/gpu/drm/drm_crtc_internal.h | 19 +-
>>> drivers/gpu/drm/drm_debugfs.c | 7 +
>>> drivers/gpu/drm/drm_drv.c | 8 +
>>> drivers/gpu/drm/drm_dumb_buffers.c | 33 ++-
>>> drivers/gpu/drm/drm_fb_cma_helper.c | 380
>>> +++---------------------
>>> drivers/gpu/drm/drm_fb_helper.c | 330
>>> ++++++++++++++++++++-
>>> drivers/gpu/drm/drm_file.c | 304 ++++++++++---------
>>> drivers/gpu/drm/drm_framebuffer.c | 42 ++-
>>> drivers/gpu/drm/drm_internal.h | 2 +
>>> drivers/gpu/drm/drm_ioctl.c | 4 +-
>>> drivers/gpu/drm/drm_probe_helper.c | 3 +
>>> drivers/gpu/drm/pl111/pl111_drv.c | 2 +
>>> drivers/gpu/drm/tinydrm/core/tinydrm-core.c | 3 +-
>>> drivers/gpu/drm/tinydrm/ili9225.c | 1 -
>>> drivers/gpu/drm/tinydrm/mi0283qt.c | 1 -
>>> drivers/gpu/drm/tinydrm/st7586.c | 1 -
>>> drivers/gpu/drm/tinydrm/st7735r.c | 1 -
>>> include/drm/drm_client.h | 156 ++++++++++
>>> include/drm/drm_device.h | 21 ++
>>> include/drm/drm_fb_cma_helper.h | 6 -
>>> include/drm/drm_fb_helper.h | 38 +++
>>> 25 files changed, 1298 insertions(+), 514 deletions(-)
>>> create mode 100644 Documentation/gpu/drm-client.rst
>>> create mode 100644 drivers/gpu/drm/drm_client.c
>>> create mode 100644 include/drm/drm_client.h
>>>
>>> --
>>> 2.15.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
More information about the dri-devel
mailing list