* [PATCH 0/5] drm/udl: Convert to generic fbdev emulation
@ 2019-10-24 14:42 Thomas Zimmermann
2019-10-24 14:42 ` [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory Thomas Zimmermann
` (4 more replies)
0 siblings, 5 replies; 31+ messages in thread
From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw)
To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel
This patchset replaces udl's fbdev code with the generic implementation.
The first patch fixes a bug that didn't trigger yet because the current
fbdev never unmaps the BO. Patches 2 to 3 add missing interfaces to the
udl driver. Patch 4 sets mapping flags. In the final patch, we remove a
lot of code and set a few helpers instead.
The patchset was tested by running the fbdev console, X11, and Weston on
a DisplayLink adapter.
Thomas Zimmermann (5):
drm/udl: Clear BO vmapping pointer after unmapping BO memory
drm/udl: Set drm_driver.gem_prime_mmap
drm/udl: Add GEM object functions for free(), vmap(), and vunmap()
drm/udl: Map BO memory pages in unencrypted mode
drm/udl: Replace fbdev code with generic emulation
drivers/gpu/drm/udl/udl_drv.c | 4 +
drivers/gpu/drm/udl/udl_drv.h | 4 -
drivers/gpu/drm/udl/udl_fb.c | 263 +-----------------------------
drivers/gpu/drm/udl/udl_gem.c | 40 ++++-
drivers/gpu/drm/udl/udl_main.c | 2 -
drivers/gpu/drm/udl/udl_modeset.c | 3 +-
6 files changed, 48 insertions(+), 268 deletions(-)
--
2.23.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 31+ messages in thread* [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann @ 2019-10-24 14:42 ` Thomas Zimmermann 2019-10-25 7:39 ` Daniel Vetter 2019-10-24 14:42 ` [PATCH 2/5] drm/udl: Set drm_driver.gem_prime_mmap Thomas Zimmermann ` (3 subsequent siblings) 4 siblings, 1 reply; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw) To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel Unmapping the BO memory with udl_gem_vunmap() creates a dangling pointer in struct udl_gem_object.vmapping. This can crash udl_handle_damage(), which check the pointer's value for NULL. Clear the pointer to NULL and let udl_handle_damage() re-establish the mapping if necessary. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/udl/udl_gem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index b23a5c2fcd80..3ea0cd9ae2d6 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -174,6 +174,7 @@ void udl_gem_vunmap(struct udl_gem_object *obj) } vunmap(obj->vmapping); + obj->vmapping = NULL; udl_gem_put_pages(obj); } -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory 2019-10-24 14:42 ` [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory Thomas Zimmermann @ 2019-10-25 7:39 ` Daniel Vetter 0 siblings, 0 replies; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 7:39 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: sean, dri-devel, airlied, sam On Thu, Oct 24, 2019 at 04:42:33PM +0200, Thomas Zimmermann wrote: > Unmapping the BO memory with udl_gem_vunmap() creates a dangling pointer > in struct udl_gem_object.vmapping. This can crash udl_handle_damage(), > which check the pointer's value for NULL. Clear the pointer to NULL and > let udl_handle_damage() re-establish the mapping if necessary. > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Hm right now this is not a problem, becase we remove the vmapping only when we free the underlying object. If that changes somehow, then what we actually need is to start refcount the vmapping (and drop the trick in udl_handle_damage and unconditionally vmap/vunmap). Might be easier to just cut over to shmem helpers. -Daniel > --- > drivers/gpu/drm/udl/udl_gem.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c > index b23a5c2fcd80..3ea0cd9ae2d6 100644 > --- a/drivers/gpu/drm/udl/udl_gem.c > +++ b/drivers/gpu/drm/udl/udl_gem.c > @@ -174,6 +174,7 @@ void udl_gem_vunmap(struct udl_gem_object *obj) > } > > vunmap(obj->vmapping); > + obj->vmapping = NULL; > > udl_gem_put_pages(obj); > } > -- > 2.23.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 2/5] drm/udl: Set drm_driver.gem_prime_mmap 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory Thomas Zimmermann @ 2019-10-24 14:42 ` Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() Thomas Zimmermann ` (2 subsequent siblings) 4 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw) To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel This interface is required by the mmap support of generic fbdev emulation. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/udl/udl_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 8426669433e4..15ad7a338f9d 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -74,6 +74,7 @@ static struct drm_driver driver = { .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = udl_gem_prime_export, .gem_prime_import = udl_gem_prime_import, + .gem_prime_mmap = drm_gem_prime_mmap, .name = DRIVER_NAME, .desc = DRIVER_DESC, -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 2/5] drm/udl: Set drm_driver.gem_prime_mmap Thomas Zimmermann @ 2019-10-24 14:42 ` Thomas Zimmermann 2019-10-25 7:40 ` Daniel Vetter 2019-10-24 14:42 ` [PATCH 4/5] drm/udl: Map BO memory pages in unencrypted mode Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation Thomas Zimmermann 4 siblings, 1 reply; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw) To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel Implementing vmap() and vunmap() of struct drm_gem_object_funcs is required by generic fbdev emulation. Supporting free() is easy as well. More udl-specific interfaces can probably be replaced by GEM object functions in later patches. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 3ea0cd9ae2d6..6ca097c270d6 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -11,6 +11,8 @@ #include "udl_drv.h" +static const struct drm_gem_object_funcs udl_gem_object_funcs; + struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, size_t size) { @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, return NULL; } + obj->base.funcs = &udl_gem_object_funcs; obj->flags = UDL_BO_CACHEABLE; return obj; } @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, mutex_unlock(&udl->gem_lock); return ret; } + +/* + * Helpers for struct drm_gem_object_funcs + */ + +static void udl_gem_object_free(struct drm_gem_object *obj) +{ + udl_gem_free_object(obj); +} + +static void *udl_gem_object_vmap(struct drm_gem_object *obj) +{ + struct udl_gem_object *uobj = to_udl_bo(obj); + int ret; + + ret = udl_gem_vmap(uobj); + if (ret) + return ERR_PTR(ret); + return uobj->vmapping; +} + +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) +{ + return udl_gem_vunmap(to_udl_bo(obj)); +} + +static const struct drm_gem_object_funcs udl_gem_object_funcs = { + .free = udl_gem_object_free, + .vmap = udl_gem_object_vmap, + .vunmap = udl_gem_object_vunmap, +}; -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() 2019-10-24 14:42 ` [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() Thomas Zimmermann @ 2019-10-25 7:40 ` Daniel Vetter 2019-10-25 7:59 ` Thomas Zimmermann 0 siblings, 1 reply; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 7:40 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: sean, dri-devel, airlied, sam On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: > Implementing vmap() and vunmap() of struct drm_gem_object_funcs is > required by generic fbdev emulation. Supporting free() is easy as > well. More udl-specific interfaces can probably be replaced by GEM > object functions in later patches. > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > --- > drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c > index 3ea0cd9ae2d6..6ca097c270d6 100644 > --- a/drivers/gpu/drm/udl/udl_gem.c > +++ b/drivers/gpu/drm/udl/udl_gem.c > @@ -11,6 +11,8 @@ > > #include "udl_drv.h" > > +static const struct drm_gem_object_funcs udl_gem_object_funcs; > + > struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > size_t size) > { > @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > return NULL; > } > > + obj->base.funcs = &udl_gem_object_funcs; > obj->flags = UDL_BO_CACHEABLE; > return obj; > } > @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, > mutex_unlock(&udl->gem_lock); > return ret; > } > + > +/* > + * Helpers for struct drm_gem_object_funcs > + */ > + > +static void udl_gem_object_free(struct drm_gem_object *obj) > +{ > + udl_gem_free_object(obj); > +} > + > +static void *udl_gem_object_vmap(struct drm_gem_object *obj) > +{ > + struct udl_gem_object *uobj = to_udl_bo(obj); > + int ret; > + > + ret = udl_gem_vmap(uobj); > + if (ret) > + return ERR_PTR(ret); > + return uobj->vmapping; > +} > + > +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) > +{ > + return udl_gem_vunmap(to_udl_bo(obj)); > +} > + > +static const struct drm_gem_object_funcs udl_gem_object_funcs = { > + .free = udl_gem_object_free, > + .vmap = udl_gem_object_vmap, > + .vunmap = udl_gem_object_vunmap, Yeah this doesn't work, you need to refcount the vmap here I think. I'd say simpler to first cut over to shmem helpers. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 7:59 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 7:59 UTC (permalink / raw) To: Daniel Vetter; +Cc: sam, airlied, sean, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 3262 bytes --] Hi Am 25.10.19 um 09:40 schrieb Daniel Vetter: > On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >> required by generic fbdev emulation. Supporting free() is easy as >> well. More udl-specific interfaces can probably be replaced by GEM >> object functions in later patches. >> >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >> --- >> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >> 1 file changed, 34 insertions(+) >> >> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >> index 3ea0cd9ae2d6..6ca097c270d6 100644 >> --- a/drivers/gpu/drm/udl/udl_gem.c >> +++ b/drivers/gpu/drm/udl/udl_gem.c >> @@ -11,6 +11,8 @@ >> >> #include "udl_drv.h" >> >> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >> + >> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >> size_t size) >> { >> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >> return NULL; >> } >> >> + obj->base.funcs = &udl_gem_object_funcs; >> obj->flags = UDL_BO_CACHEABLE; >> return obj; >> } >> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >> mutex_unlock(&udl->gem_lock); >> return ret; >> } >> + >> +/* >> + * Helpers for struct drm_gem_object_funcs >> + */ >> + >> +static void udl_gem_object_free(struct drm_gem_object *obj) >> +{ >> + udl_gem_free_object(obj); >> +} >> + >> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >> +{ >> + struct udl_gem_object *uobj = to_udl_bo(obj); >> + int ret; >> + >> + ret = udl_gem_vmap(uobj); >> + if (ret) >> + return ERR_PTR(ret); >> + return uobj->vmapping; >> +} >> + >> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >> +{ >> + return udl_gem_vunmap(to_udl_bo(obj)); >> +} >> + >> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >> + .free = udl_gem_object_free, >> + .vmap = udl_gem_object_vmap, >> + .vunmap = udl_gem_object_vunmap, > > Yeah this doesn't work, you need to refcount the vmap here I think. I'd I see. Should have thought of that... > say simpler to first cut over to shmem helpers. Right. I was already attempting the conversion and the udl gem is more or less the same as shmem, except for the flags field. [1] The flag signals page attributes for mmap-ing [2]. For prime-imported BOs its is set to writecombining, and for local BOs it is set to cached. Shmem always maps with writecombining. I don't see why udl BOs are special wrt to mmap-ing. It seems to be some kind of optimization. Do you have an idea? Best regards Thomas [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 > -Daniel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 7:59 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 7:59 UTC (permalink / raw) To: Daniel Vetter; +Cc: sam, airlied, sean, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 3262 bytes --] Hi Am 25.10.19 um 09:40 schrieb Daniel Vetter: > On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >> required by generic fbdev emulation. Supporting free() is easy as >> well. More udl-specific interfaces can probably be replaced by GEM >> object functions in later patches. >> >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >> --- >> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >> 1 file changed, 34 insertions(+) >> >> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >> index 3ea0cd9ae2d6..6ca097c270d6 100644 >> --- a/drivers/gpu/drm/udl/udl_gem.c >> +++ b/drivers/gpu/drm/udl/udl_gem.c >> @@ -11,6 +11,8 @@ >> >> #include "udl_drv.h" >> >> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >> + >> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >> size_t size) >> { >> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >> return NULL; >> } >> >> + obj->base.funcs = &udl_gem_object_funcs; >> obj->flags = UDL_BO_CACHEABLE; >> return obj; >> } >> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >> mutex_unlock(&udl->gem_lock); >> return ret; >> } >> + >> +/* >> + * Helpers for struct drm_gem_object_funcs >> + */ >> + >> +static void udl_gem_object_free(struct drm_gem_object *obj) >> +{ >> + udl_gem_free_object(obj); >> +} >> + >> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >> +{ >> + struct udl_gem_object *uobj = to_udl_bo(obj); >> + int ret; >> + >> + ret = udl_gem_vmap(uobj); >> + if (ret) >> + return ERR_PTR(ret); >> + return uobj->vmapping; >> +} >> + >> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >> +{ >> + return udl_gem_vunmap(to_udl_bo(obj)); >> +} >> + >> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >> + .free = udl_gem_object_free, >> + .vmap = udl_gem_object_vmap, >> + .vunmap = udl_gem_object_vunmap, > > Yeah this doesn't work, you need to refcount the vmap here I think. I'd I see. Should have thought of that... > say simpler to first cut over to shmem helpers. Right. I was already attempting the conversion and the udl gem is more or less the same as shmem, except for the flags field. [1] The flag signals page attributes for mmap-ing [2]. For prime-imported BOs its is set to writecombining, and for local BOs it is set to cached. Shmem always maps with writecombining. I don't see why udl BOs are special wrt to mmap-ing. It seems to be some kind of optimization. Do you have an idea? Best regards Thomas [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 > -Daniel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 9:28 ` Daniel Vetter 0 siblings, 0 replies; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 9:28 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote > > Hi > > Am 25.10.19 um 09:40 schrieb Daniel Vetter: > > On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: > >> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is > >> required by generic fbdev emulation. Supporting free() is easy as > >> well. More udl-specific interfaces can probably be replaced by GEM > >> object functions in later patches. > >> > >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > >> --- > >> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ > >> 1 file changed, 34 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c > >> index 3ea0cd9ae2d6..6ca097c270d6 100644 > >> --- a/drivers/gpu/drm/udl/udl_gem.c > >> +++ b/drivers/gpu/drm/udl/udl_gem.c > >> @@ -11,6 +11,8 @@ > >> > >> #include "udl_drv.h" > >> > >> +static const struct drm_gem_object_funcs udl_gem_object_funcs; > >> + > >> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > >> size_t size) > >> { > >> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > >> return NULL; > >> } > >> > >> + obj->base.funcs = &udl_gem_object_funcs; > >> obj->flags = UDL_BO_CACHEABLE; > >> return obj; > >> } > >> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, > >> mutex_unlock(&udl->gem_lock); > >> return ret; > >> } > >> + > >> +/* > >> + * Helpers for struct drm_gem_object_funcs > >> + */ > >> + > >> +static void udl_gem_object_free(struct drm_gem_object *obj) > >> +{ > >> + udl_gem_free_object(obj); > >> +} > >> + > >> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) > >> +{ > >> + struct udl_gem_object *uobj = to_udl_bo(obj); > >> + int ret; > >> + > >> + ret = udl_gem_vmap(uobj); > >> + if (ret) > >> + return ERR_PTR(ret); > >> + return uobj->vmapping; > >> +} > >> + > >> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) > >> +{ > >> + return udl_gem_vunmap(to_udl_bo(obj)); > >> +} > >> + > >> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { > >> + .free = udl_gem_object_free, > >> + .vmap = udl_gem_object_vmap, > >> + .vunmap = udl_gem_object_vunmap, > > > > Yeah this doesn't work, you need to refcount the vmap here I think. I'd > > I see. Should have thought of that... > > > say simpler to first cut over to shmem helpers. > > Right. I was already attempting the conversion and the udl gem is more > or less the same as shmem, except for the flags field. [1] The flag > signals page attributes for mmap-ing [2]. For prime-imported BOs its is > set to writecombining, and for local BOs it is set to cached. Shmem > always maps with writecombining. > > I don't see why udl BOs are special wrt to mmap-ing. It seems to be some > kind of optimization. Do you have an idea? > > Best regards > Thomas > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 > [2] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 udl doesn't set prefer_shadow = 1, which means compositors will render directly into the buffer. And for that you want caching. For imported dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess udl would need to get the dma_buf_begin/end_cpu_access calls added (and that would probably be faster than going with wc for everything). So we do want cachable, it's going to suck otherwise. But that should be fairly easy to do by overwriting the obj->mmap callback and wrapping it around the shmem one. What surprises me more is that udl supports mmap on imported dma-buf, that's some real quirky stuff. Not sure there's really other drivers doing that. Might be easier to rip that out :-) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 9:28 ` Daniel Vetter 0 siblings, 0 replies; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 9:28 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote > > Hi > > Am 25.10.19 um 09:40 schrieb Daniel Vetter: > > On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: > >> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is > >> required by generic fbdev emulation. Supporting free() is easy as > >> well. More udl-specific interfaces can probably be replaced by GEM > >> object functions in later patches. > >> > >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > >> --- > >> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ > >> 1 file changed, 34 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c > >> index 3ea0cd9ae2d6..6ca097c270d6 100644 > >> --- a/drivers/gpu/drm/udl/udl_gem.c > >> +++ b/drivers/gpu/drm/udl/udl_gem.c > >> @@ -11,6 +11,8 @@ > >> > >> #include "udl_drv.h" > >> > >> +static const struct drm_gem_object_funcs udl_gem_object_funcs; > >> + > >> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > >> size_t size) > >> { > >> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, > >> return NULL; > >> } > >> > >> + obj->base.funcs = &udl_gem_object_funcs; > >> obj->flags = UDL_BO_CACHEABLE; > >> return obj; > >> } > >> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, > >> mutex_unlock(&udl->gem_lock); > >> return ret; > >> } > >> + > >> +/* > >> + * Helpers for struct drm_gem_object_funcs > >> + */ > >> + > >> +static void udl_gem_object_free(struct drm_gem_object *obj) > >> +{ > >> + udl_gem_free_object(obj); > >> +} > >> + > >> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) > >> +{ > >> + struct udl_gem_object *uobj = to_udl_bo(obj); > >> + int ret; > >> + > >> + ret = udl_gem_vmap(uobj); > >> + if (ret) > >> + return ERR_PTR(ret); > >> + return uobj->vmapping; > >> +} > >> + > >> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) > >> +{ > >> + return udl_gem_vunmap(to_udl_bo(obj)); > >> +} > >> + > >> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { > >> + .free = udl_gem_object_free, > >> + .vmap = udl_gem_object_vmap, > >> + .vunmap = udl_gem_object_vunmap, > > > > Yeah this doesn't work, you need to refcount the vmap here I think. I'd > > I see. Should have thought of that... > > > say simpler to first cut over to shmem helpers. > > Right. I was already attempting the conversion and the udl gem is more > or less the same as shmem, except for the flags field. [1] The flag > signals page attributes for mmap-ing [2]. For prime-imported BOs its is > set to writecombining, and for local BOs it is set to cached. Shmem > always maps with writecombining. > > I don't see why udl BOs are special wrt to mmap-ing. It seems to be some > kind of optimization. Do you have an idea? > > Best regards > Thomas > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 > [2] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 udl doesn't set prefer_shadow = 1, which means compositors will render directly into the buffer. And for that you want caching. For imported dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess udl would need to get the dma_buf_begin/end_cpu_access calls added (and that would probably be faster than going with wc for everything). So we do want cachable, it's going to suck otherwise. But that should be fairly easy to do by overwriting the obj->mmap callback and wrapping it around the shmem one. What surprises me more is that udl supports mmap on imported dma-buf, that's some real quirky stuff. Not sure there's really other drivers doing that. Might be easier to rip that out :-) -Daniel -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 10:12 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 10:12 UTC (permalink / raw) To: Daniel Vetter; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 4876 bytes --] Hi Am 25.10.19 um 11:28 schrieb Daniel Vetter: > On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >> >> Hi >> >> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>> required by generic fbdev emulation. Supporting free() is easy as >>>> well. More udl-specific interfaces can probably be replaced by GEM >>>> object functions in later patches. >>>> >>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>> --- >>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>> 1 file changed, 34 insertions(+) >>>> >>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>> @@ -11,6 +11,8 @@ >>>> >>>> #include "udl_drv.h" >>>> >>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>> + >>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>> size_t size) >>>> { >>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>> return NULL; >>>> } >>>> >>>> + obj->base.funcs = &udl_gem_object_funcs; >>>> obj->flags = UDL_BO_CACHEABLE; >>>> return obj; >>>> } >>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>> mutex_unlock(&udl->gem_lock); >>>> return ret; >>>> } >>>> + >>>> +/* >>>> + * Helpers for struct drm_gem_object_funcs >>>> + */ >>>> + >>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>> +{ >>>> + udl_gem_free_object(obj); >>>> +} >>>> + >>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>> +{ >>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>> + int ret; >>>> + >>>> + ret = udl_gem_vmap(uobj); >>>> + if (ret) >>>> + return ERR_PTR(ret); >>>> + return uobj->vmapping; >>>> +} >>>> + >>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>> +{ >>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>> +} >>>> + >>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>> + .free = udl_gem_object_free, >>>> + .vmap = udl_gem_object_vmap, >>>> + .vunmap = udl_gem_object_vunmap, >>> >>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >> >> I see. Should have thought of that... >> >>> say simpler to first cut over to shmem helpers. >> >> Right. I was already attempting the conversion and the udl gem is more >> or less the same as shmem, except for the flags field. [1] The flag >> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >> set to writecombining, and for local BOs it is set to cached. Shmem >> always maps with writecombining. >> >> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >> kind of optimization. Do you have an idea? >> >> Best regards >> Thomas >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >> [2] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 > > udl doesn't set prefer_shadow = 1, which means compositors will render > directly into the buffer. And for that you want caching. For imported > dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess > udl would need to get the dma_buf_begin/end_cpu_access calls added > (and that would probably be faster than going with wc for everything). > So we do want cachable, it's going to suck otherwise. Thanks for clarifying. Actually, it does have these calls in its dirty handler. [1] > > But that should be fairly easy to do by overwriting the obj->mmap > callback and wrapping it around the shmem one. Is there a reason why shmem doesn't implement the wc-vs.cached logic? Could this be added? (I'm just trying to understand the available options here before attempting to do a conversion.) Best regards Thomas > > What surprises me more is that udl supports mmap on imported dma-buf, > that's some real quirky stuff. Not sure there's really other drivers > doing that. Might be easier to rip that out :-) > -Daniel > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 10:12 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 10:12 UTC (permalink / raw) To: Daniel Vetter; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 4876 bytes --] Hi Am 25.10.19 um 11:28 schrieb Daniel Vetter: > On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >> >> Hi >> >> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>> required by generic fbdev emulation. Supporting free() is easy as >>>> well. More udl-specific interfaces can probably be replaced by GEM >>>> object functions in later patches. >>>> >>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>> --- >>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>> 1 file changed, 34 insertions(+) >>>> >>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>> @@ -11,6 +11,8 @@ >>>> >>>> #include "udl_drv.h" >>>> >>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>> + >>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>> size_t size) >>>> { >>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>> return NULL; >>>> } >>>> >>>> + obj->base.funcs = &udl_gem_object_funcs; >>>> obj->flags = UDL_BO_CACHEABLE; >>>> return obj; >>>> } >>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>> mutex_unlock(&udl->gem_lock); >>>> return ret; >>>> } >>>> + >>>> +/* >>>> + * Helpers for struct drm_gem_object_funcs >>>> + */ >>>> + >>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>> +{ >>>> + udl_gem_free_object(obj); >>>> +} >>>> + >>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>> +{ >>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>> + int ret; >>>> + >>>> + ret = udl_gem_vmap(uobj); >>>> + if (ret) >>>> + return ERR_PTR(ret); >>>> + return uobj->vmapping; >>>> +} >>>> + >>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>> +{ >>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>> +} >>>> + >>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>> + .free = udl_gem_object_free, >>>> + .vmap = udl_gem_object_vmap, >>>> + .vunmap = udl_gem_object_vunmap, >>> >>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >> >> I see. Should have thought of that... >> >>> say simpler to first cut over to shmem helpers. >> >> Right. I was already attempting the conversion and the udl gem is more >> or less the same as shmem, except for the flags field. [1] The flag >> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >> set to writecombining, and for local BOs it is set to cached. Shmem >> always maps with writecombining. >> >> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >> kind of optimization. Do you have an idea? >> >> Best regards >> Thomas >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >> [2] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 > > udl doesn't set prefer_shadow = 1, which means compositors will render > directly into the buffer. And for that you want caching. For imported > dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess > udl would need to get the dma_buf_begin/end_cpu_access calls added > (and that would probably be faster than going with wc for everything). > So we do want cachable, it's going to suck otherwise. Thanks for clarifying. Actually, it does have these calls in its dirty handler. [1] > > But that should be fairly easy to do by overwriting the obj->mmap > callback and wrapping it around the shmem one. Is there a reason why shmem doesn't implement the wc-vs.cached logic? Could this be added? (I'm just trying to understand the available options here before attempting to do a conversion.) Best regards Thomas > > What surprises me more is that udl supports mmap on imported dma-buf, > that's some real quirky stuff. Not sure there's really other drivers > doing that. Might be easier to rip that out :-) > -Daniel > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 11:44 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 11:44 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Sean Paul, Dave Airlie, Sam Ravnborg, dri-devel Den 25.10.2019 12.12, skrev Thomas Zimmermann: > Hi > > Am 25.10.19 um 11:28 schrieb Daniel Vetter: >> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>> >>> Hi >>> >>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>> object functions in later patches. >>>>> >>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>> --- >>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>> 1 file changed, 34 insertions(+) >>>>> >>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>> @@ -11,6 +11,8 @@ >>>>> >>>>> #include "udl_drv.h" >>>>> >>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>> + >>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>> size_t size) >>>>> { >>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>> return NULL; >>>>> } >>>>> >>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>> obj->flags = UDL_BO_CACHEABLE; >>>>> return obj; >>>>> } >>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>> mutex_unlock(&udl->gem_lock); >>>>> return ret; >>>>> } >>>>> + >>>>> +/* >>>>> + * Helpers for struct drm_gem_object_funcs >>>>> + */ >>>>> + >>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>> +{ >>>>> + udl_gem_free_object(obj); >>>>> +} >>>>> + >>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>> +{ >>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>> + int ret; >>>>> + >>>>> + ret = udl_gem_vmap(uobj); >>>>> + if (ret) >>>>> + return ERR_PTR(ret); >>>>> + return uobj->vmapping; >>>>> +} >>>>> + >>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>> +{ >>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>> +} >>>>> + >>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>> + .free = udl_gem_object_free, >>>>> + .vmap = udl_gem_object_vmap, >>>>> + .vunmap = udl_gem_object_vunmap, >>>> >>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>> >>> I see. Should have thought of that... >>> >>>> say simpler to first cut over to shmem helpers. >>> >>> Right. I was already attempting the conversion and the udl gem is more >>> or less the same as shmem, except for the flags field. [1] The flag >>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>> set to writecombining, and for local BOs it is set to cached. Shmem >>> always maps with writecombining. >>> >>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>> kind of optimization. Do you have an idea? >>> >>> Best regards >>> Thomas >>> >>> [1] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>> [2] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >> >> udl doesn't set prefer_shadow = 1, which means compositors will render >> directly into the buffer. And for that you want caching. For imported >> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >> udl would need to get the dma_buf_begin/end_cpu_access calls added >> (and that would probably be faster than going with wc for everything). >> So we do want cachable, it's going to suck otherwise. > > Thanks for clarifying. Actually, it does have these calls in its dirty > handler. [1] > >> >> But that should be fairly easy to do by overwriting the obj->mmap >> callback and wrapping it around the shmem one. > > Is there a reason why shmem doesn't implement the wc-vs.cached logic? > Could this be added? > I had a flag to set this in the initial version of the shmem helper modeled after udl, but Thomas Hellstrom brought up a question and it was dropped. The issue was beyond my understanding: [PATCH v3 0/2] drm: Add shmem GEM library https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html In tinydrm I have sped up uncached writes on arm by copying one pixel line at a time into a temporary buffer before accessing the individual bytes. See drm_fb_swab16(). Noralf. > (I'm just trying to understand the available options here before > attempting to do a conversion.) > > Best regards > Thomas > >> >> What surprises me more is that udl supports mmap on imported dma-buf, >> that's some real quirky stuff. Not sure there's really other drivers >> doing that. Might be easier to rip that out :-) >> -Daniel >> > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 > > > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 11:44 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 11:44 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Sean Paul, Dave Airlie, Sam Ravnborg, dri-devel Den 25.10.2019 12.12, skrev Thomas Zimmermann: > Hi > > Am 25.10.19 um 11:28 schrieb Daniel Vetter: >> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>> >>> Hi >>> >>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>> object functions in later patches. >>>>> >>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>> --- >>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>> 1 file changed, 34 insertions(+) >>>>> >>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>> @@ -11,6 +11,8 @@ >>>>> >>>>> #include "udl_drv.h" >>>>> >>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>> + >>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>> size_t size) >>>>> { >>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>> return NULL; >>>>> } >>>>> >>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>> obj->flags = UDL_BO_CACHEABLE; >>>>> return obj; >>>>> } >>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>> mutex_unlock(&udl->gem_lock); >>>>> return ret; >>>>> } >>>>> + >>>>> +/* >>>>> + * Helpers for struct drm_gem_object_funcs >>>>> + */ >>>>> + >>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>> +{ >>>>> + udl_gem_free_object(obj); >>>>> +} >>>>> + >>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>> +{ >>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>> + int ret; >>>>> + >>>>> + ret = udl_gem_vmap(uobj); >>>>> + if (ret) >>>>> + return ERR_PTR(ret); >>>>> + return uobj->vmapping; >>>>> +} >>>>> + >>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>> +{ >>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>> +} >>>>> + >>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>> + .free = udl_gem_object_free, >>>>> + .vmap = udl_gem_object_vmap, >>>>> + .vunmap = udl_gem_object_vunmap, >>>> >>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>> >>> I see. Should have thought of that... >>> >>>> say simpler to first cut over to shmem helpers. >>> >>> Right. I was already attempting the conversion and the udl gem is more >>> or less the same as shmem, except for the flags field. [1] The flag >>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>> set to writecombining, and for local BOs it is set to cached. Shmem >>> always maps with writecombining. >>> >>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>> kind of optimization. Do you have an idea? >>> >>> Best regards >>> Thomas >>> >>> [1] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>> [2] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >> >> udl doesn't set prefer_shadow = 1, which means compositors will render >> directly into the buffer. And for that you want caching. For imported >> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >> udl would need to get the dma_buf_begin/end_cpu_access calls added >> (and that would probably be faster than going with wc for everything). >> So we do want cachable, it's going to suck otherwise. > > Thanks for clarifying. Actually, it does have these calls in its dirty > handler. [1] > >> >> But that should be fairly easy to do by overwriting the obj->mmap >> callback and wrapping it around the shmem one. > > Is there a reason why shmem doesn't implement the wc-vs.cached logic? > Could this be added? > I had a flag to set this in the initial version of the shmem helper modeled after udl, but Thomas Hellstrom brought up a question and it was dropped. The issue was beyond my understanding: [PATCH v3 0/2] drm: Add shmem GEM library https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html In tinydrm I have sped up uncached writes on arm by copying one pixel line at a time into a temporary buffer before accessing the individual bytes. See drm_fb_swab16(). Noralf. > (I'm just trying to understand the available options here before > attempting to do a conversion.) > > Best regards > Thomas > >> >> What surprises me more is that udl supports mmap on imported dma-buf, >> that's some real quirky stuff. Not sure there's really other drivers >> doing that. Might be easier to rip that out :-) >> -Daniel >> > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 > > > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 11:47 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 11:47 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg Den 25.10.2019 13.44, skrev Noralf Trønnes: > > > Den 25.10.2019 12.12, skrev Thomas Zimmermann: >> Hi >> >> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>> >>>> Hi >>>> >>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>> object functions in later patches. >>>>>> >>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>> --- >>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>> 1 file changed, 34 insertions(+) >>>>>> >>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>> @@ -11,6 +11,8 @@ >>>>>> >>>>>> #include "udl_drv.h" >>>>>> >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>> + >>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> size_t size) >>>>>> { >>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> return NULL; >>>>>> } >>>>>> >>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>> return obj; >>>>>> } >>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>> mutex_unlock(&udl->gem_lock); >>>>>> return ret; >>>>>> } >>>>>> + >>>>>> +/* >>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>> + */ >>>>>> + >>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + udl_gem_free_object(obj); >>>>>> +} >>>>>> + >>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>> + int ret; >>>>>> + >>>>>> + ret = udl_gem_vmap(uobj); >>>>>> + if (ret) >>>>>> + return ERR_PTR(ret); >>>>>> + return uobj->vmapping; >>>>>> +} >>>>>> + >>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>> +{ >>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>> +} >>>>>> + >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>> + .free = udl_gem_object_free, >>>>>> + .vmap = udl_gem_object_vmap, >>>>>> + .vunmap = udl_gem_object_vunmap, >>>>> >>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>> >>>> I see. Should have thought of that... >>>> >>>>> say simpler to first cut over to shmem helpers. >>>> >>>> Right. I was already attempting the conversion and the udl gem is more >>>> or less the same as shmem, except for the flags field. [1] The flag >>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>> always maps with writecombining. >>>> >>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>> kind of optimization. Do you have an idea? >>>> >>>> Best regards >>>> Thomas >>>> >>>> [1] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>> [2] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>> >>> udl doesn't set prefer_shadow = 1, which means compositors will render >>> directly into the buffer. And for that you want caching. For imported >>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>> (and that would probably be faster than going with wc for everything). >>> So we do want cachable, it's going to suck otherwise. >> >> Thanks for clarifying. Actually, it does have these calls in its dirty >> handler. [1] >> >>> >>> But that should be fairly easy to do by overwriting the obj->mmap >>> callback and wrapping it around the shmem one. >> >> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >> Could this be added? >> > > I had a flag to set this in the initial version of the shmem helper > modeled after udl, but Thomas Hellstrom brought up a question and it was > dropped. The issue was beyond my understanding: > > [PATCH v3 0/2] drm: Add shmem GEM library > https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html > > In tinydrm I have sped up uncached writes on arm by copying one pixel s/writes/reads/ > line at a time into a temporary buffer before accessing the individual > bytes. See drm_fb_swab16(). > > Noralf. > >> (I'm just trying to understand the available options here before >> attempting to do a conversion.) >> >> Best regards >> Thomas >> >>> >>> What surprises me more is that udl supports mmap on imported dma-buf, >>> that's some real quirky stuff. Not sure there's really other drivers >>> doing that. Might be easier to rip that out :-) >>> -Daniel >>> >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >> >> >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 11:47 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 11:47 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg Den 25.10.2019 13.44, skrev Noralf Trønnes: > > > Den 25.10.2019 12.12, skrev Thomas Zimmermann: >> Hi >> >> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>> >>>> Hi >>>> >>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>> object functions in later patches. >>>>>> >>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>> --- >>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>> 1 file changed, 34 insertions(+) >>>>>> >>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>> @@ -11,6 +11,8 @@ >>>>>> >>>>>> #include "udl_drv.h" >>>>>> >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>> + >>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> size_t size) >>>>>> { >>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> return NULL; >>>>>> } >>>>>> >>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>> return obj; >>>>>> } >>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>> mutex_unlock(&udl->gem_lock); >>>>>> return ret; >>>>>> } >>>>>> + >>>>>> +/* >>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>> + */ >>>>>> + >>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + udl_gem_free_object(obj); >>>>>> +} >>>>>> + >>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>> + int ret; >>>>>> + >>>>>> + ret = udl_gem_vmap(uobj); >>>>>> + if (ret) >>>>>> + return ERR_PTR(ret); >>>>>> + return uobj->vmapping; >>>>>> +} >>>>>> + >>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>> +{ >>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>> +} >>>>>> + >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>> + .free = udl_gem_object_free, >>>>>> + .vmap = udl_gem_object_vmap, >>>>>> + .vunmap = udl_gem_object_vunmap, >>>>> >>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>> >>>> I see. Should have thought of that... >>>> >>>>> say simpler to first cut over to shmem helpers. >>>> >>>> Right. I was already attempting the conversion and the udl gem is more >>>> or less the same as shmem, except for the flags field. [1] The flag >>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>> always maps with writecombining. >>>> >>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>> kind of optimization. Do you have an idea? >>>> >>>> Best regards >>>> Thomas >>>> >>>> [1] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>> [2] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>> >>> udl doesn't set prefer_shadow = 1, which means compositors will render >>> directly into the buffer. And for that you want caching. For imported >>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>> (and that would probably be faster than going with wc for everything). >>> So we do want cachable, it's going to suck otherwise. >> >> Thanks for clarifying. Actually, it does have these calls in its dirty >> handler. [1] >> >>> >>> But that should be fairly easy to do by overwriting the obj->mmap >>> callback and wrapping it around the shmem one. >> >> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >> Could this be added? >> > > I had a flag to set this in the initial version of the shmem helper > modeled after udl, but Thomas Hellstrom brought up a question and it was > dropped. The issue was beyond my understanding: > > [PATCH v3 0/2] drm: Add shmem GEM library > https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html > > In tinydrm I have sped up uncached writes on arm by copying one pixel s/writes/reads/ > line at a time into a temporary buffer before accessing the individual > bytes. See drm_fb_swab16(). > > Noralf. > >> (I'm just trying to understand the available options here before >> attempting to do a conversion.) >> >> Best regards >> Thomas >> >>> >>> What surprises me more is that udl supports mmap on imported dma-buf, >>> that's some real quirky stuff. Not sure there's really other drivers >>> doing that. Might be easier to rip that out :-) >>> -Daniel >>> >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >> >> >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 12:20 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 12:20 UTC (permalink / raw) To: Noralf Trønnes, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg, Gerd Hoffmann [-- Attachment #1.1.1: Type: text/plain, Size: 6435 bytes --] (cc: Gerd) Hi Am 25.10.19 um 13:44 schrieb Noralf Trønnes: > > > Den 25.10.2019 12.12, skrev Thomas Zimmermann: >> Hi >> >> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>> >>>> Hi >>>> >>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>> object functions in later patches. >>>>>> >>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>> --- >>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>> 1 file changed, 34 insertions(+) >>>>>> >>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>> @@ -11,6 +11,8 @@ >>>>>> >>>>>> #include "udl_drv.h" >>>>>> >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>> + >>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> size_t size) >>>>>> { >>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> return NULL; >>>>>> } >>>>>> >>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>> return obj; >>>>>> } >>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>> mutex_unlock(&udl->gem_lock); >>>>>> return ret; >>>>>> } >>>>>> + >>>>>> +/* >>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>> + */ >>>>>> + >>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + udl_gem_free_object(obj); >>>>>> +} >>>>>> + >>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>> + int ret; >>>>>> + >>>>>> + ret = udl_gem_vmap(uobj); >>>>>> + if (ret) >>>>>> + return ERR_PTR(ret); >>>>>> + return uobj->vmapping; >>>>>> +} >>>>>> + >>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>> +{ >>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>> +} >>>>>> + >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>> + .free = udl_gem_object_free, >>>>>> + .vmap = udl_gem_object_vmap, >>>>>> + .vunmap = udl_gem_object_vunmap, >>>>> >>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>> >>>> I see. Should have thought of that... >>>> >>>>> say simpler to first cut over to shmem helpers. >>>> >>>> Right. I was already attempting the conversion and the udl gem is more >>>> or less the same as shmem, except for the flags field. [1] The flag >>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>> always maps with writecombining. >>>> >>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>> kind of optimization. Do you have an idea? >>>> >>>> Best regards >>>> Thomas >>>> >>>> [1] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>> [2] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>> >>> udl doesn't set prefer_shadow = 1, which means compositors will render >>> directly into the buffer. And for that you want caching. For imported >>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>> (and that would probably be faster than going with wc for everything). >>> So we do want cachable, it's going to suck otherwise. >> >> Thanks for clarifying. Actually, it does have these calls in its dirty >> handler. [1] >> >>> >>> But that should be fairly easy to do by overwriting the obj->mmap >>> callback and wrapping it around the shmem one. >> >> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >> Could this be added? >> > > I had a flag to set this in the initial version of the shmem helper > modeled after udl, but Thomas Hellstrom brought up a question and it was > dropped. The issue was beyond my understanding: > > [PATCH v3 0/2] drm: Add shmem GEM library > https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html If I understand that discussion correctly, the concern was that write combining and shared memory would not work well together. So you went with always-cached? Just recently, Gerd added unconditional write combining in rev 0be8958936. Best regards Thomas > > In tinydrm I have sped up uncached writes on arm by copying one pixel > line at a time into a temporary buffer before accessing the individual > bytes. See drm_fb_swab16(). > > Noralf. > >> (I'm just trying to understand the available options here before >> attempting to do a conversion.) >> >> Best regards >> Thomas >> >>> >>> What surprises me more is that udl supports mmap on imported dma-buf, >>> that's some real quirky stuff. Not sure there's really other drivers >>> doing that. Might be easier to rip that out :-) >>> -Daniel >>> >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >> >> >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 12:20 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 12:20 UTC (permalink / raw) To: Noralf Trønnes, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg, Gerd Hoffmann [-- Attachment #1.1.1: Type: text/plain, Size: 6435 bytes --] (cc: Gerd) Hi Am 25.10.19 um 13:44 schrieb Noralf Trønnes: > > > Den 25.10.2019 12.12, skrev Thomas Zimmermann: >> Hi >> >> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>> >>>> Hi >>>> >>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>> object functions in later patches. >>>>>> >>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>> --- >>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>> 1 file changed, 34 insertions(+) >>>>>> >>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>> @@ -11,6 +11,8 @@ >>>>>> >>>>>> #include "udl_drv.h" >>>>>> >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>> + >>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> size_t size) >>>>>> { >>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>> return NULL; >>>>>> } >>>>>> >>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>> return obj; >>>>>> } >>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>> mutex_unlock(&udl->gem_lock); >>>>>> return ret; >>>>>> } >>>>>> + >>>>>> +/* >>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>> + */ >>>>>> + >>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + udl_gem_free_object(obj); >>>>>> +} >>>>>> + >>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>> +{ >>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>> + int ret; >>>>>> + >>>>>> + ret = udl_gem_vmap(uobj); >>>>>> + if (ret) >>>>>> + return ERR_PTR(ret); >>>>>> + return uobj->vmapping; >>>>>> +} >>>>>> + >>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>> +{ >>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>> +} >>>>>> + >>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>> + .free = udl_gem_object_free, >>>>>> + .vmap = udl_gem_object_vmap, >>>>>> + .vunmap = udl_gem_object_vunmap, >>>>> >>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>> >>>> I see. Should have thought of that... >>>> >>>>> say simpler to first cut over to shmem helpers. >>>> >>>> Right. I was already attempting the conversion and the udl gem is more >>>> or less the same as shmem, except for the flags field. [1] The flag >>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>> always maps with writecombining. >>>> >>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>> kind of optimization. Do you have an idea? >>>> >>>> Best regards >>>> Thomas >>>> >>>> [1] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>> [2] >>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>> >>> udl doesn't set prefer_shadow = 1, which means compositors will render >>> directly into the buffer. And for that you want caching. For imported >>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>> (and that would probably be faster than going with wc for everything). >>> So we do want cachable, it's going to suck otherwise. >> >> Thanks for clarifying. Actually, it does have these calls in its dirty >> handler. [1] >> >>> >>> But that should be fairly easy to do by overwriting the obj->mmap >>> callback and wrapping it around the shmem one. >> >> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >> Could this be added? >> > > I had a flag to set this in the initial version of the shmem helper > modeled after udl, but Thomas Hellstrom brought up a question and it was > dropped. The issue was beyond my understanding: > > [PATCH v3 0/2] drm: Add shmem GEM library > https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html If I understand that discussion correctly, the concern was that write combining and shared memory would not work well together. So you went with always-cached? Just recently, Gerd added unconditional write combining in rev 0be8958936. Best regards Thomas > > In tinydrm I have sped up uncached writes on arm by copying one pixel > line at a time into a temporary buffer before accessing the individual > bytes. See drm_fb_swab16(). > > Noralf. > >> (I'm just trying to understand the available options here before >> attempting to do a conversion.) >> >> Best regards >> Thomas >> >>> >>> What surprises me more is that udl supports mmap on imported dma-buf, >>> that's some real quirky stuff. Not sure there's really other drivers >>> doing that. Might be easier to rip that out :-) >>> -Daniel >>> >> >> [1] >> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >> >> >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() 2019-10-25 12:20 ` Thomas Zimmermann (?) @ 2019-10-25 13:32 ` Gerd Hoffmann 2019-10-25 14:53 ` Thomas Zimmermann -1 siblings, 1 reply; 31+ messages in thread From: Gerd Hoffmann @ 2019-10-25 13:32 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: Sean Paul, dri-devel, Dave Airlie, Sam Ravnborg Hi, > > I had a flag to set this in the initial version of the shmem helper > > modeled after udl, but Thomas Hellstrom brought up a question and it was > > dropped. The issue was beyond my understanding: > > > > [PATCH v3 0/2] drm: Add shmem GEM library > > https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html > > If I understand that discussion correctly, the concern was that write > combining and shared memory would not work well together. So you went > with always-cached? > > Just recently, Gerd added unconditional write combining in rev 0be8958936. Well, it's not really added. It's the same thing drm_gem_mmap_obj() does for you when you don't have a drm_gem_object_funcs.mmap callback. But, yes, the reason this is done in the driver's mmap() callback with the new mmap code path is to give drivers the option to override this by supplying their own mmap() handler. So going with shmem helpers + custom mmap callback is a reasonable approach. HTH, Gerd _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 14:53 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 14:53 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 1564 bytes --] Hi Am 25.10.19 um 15:32 schrieb Gerd Hoffmann: > Hi, > >>> I had a flag to set this in the initial version of the shmem helper >>> modeled after udl, but Thomas Hellstrom brought up a question and it was >>> dropped. The issue was beyond my understanding: >>> >>> [PATCH v3 0/2] drm: Add shmem GEM library >>> https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html >> >> If I understand that discussion correctly, the concern was that write >> combining and shared memory would not work well together. So you went >> with always-cached? >> >> Just recently, Gerd added unconditional write combining in rev 0be8958936. > > Well, it's not really added. It's the same thing drm_gem_mmap_obj() > does for you when you don't have a drm_gem_object_funcs.mmap callback. > > But, yes, the reason this is done in the driver's mmap() callback with > the new mmap code path is to give drivers the option to override this > by supplying their own mmap() handler. So going with shmem helpers + > custom mmap callback is a reasonable approach. > > HTH, Absolutely. Thanks everyone for the feedback. Best regards Thomas > Gerd > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 14:53 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 14:53 UTC (permalink / raw) To: Gerd Hoffmann; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 1564 bytes --] Hi Am 25.10.19 um 15:32 schrieb Gerd Hoffmann: > Hi, > >>> I had a flag to set this in the initial version of the shmem helper >>> modeled after udl, but Thomas Hellstrom brought up a question and it was >>> dropped. The issue was beyond my understanding: >>> >>> [PATCH v3 0/2] drm: Add shmem GEM library >>> https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html >> >> If I understand that discussion correctly, the concern was that write >> combining and shared memory would not work well together. So you went >> with always-cached? >> >> Just recently, Gerd added unconditional write combining in rev 0be8958936. > > Well, it's not really added. It's the same thing drm_gem_mmap_obj() > does for you when you don't have a drm_gem_object_funcs.mmap callback. > > But, yes, the reason this is done in the driver's mmap() callback with > the new mmap code path is to give drivers the option to override this > by supplying their own mmap() handler. So going with shmem helpers + > custom mmap callback is a reasonable approach. > > HTH, Absolutely. Thanks everyone for the feedback. Best regards Thomas > Gerd > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 13:44 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 13:44 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg, Gerd Hoffmann Den 25.10.2019 14.20, skrev Thomas Zimmermann: > (cc: Gerd) > > Hi > > Am 25.10.19 um 13:44 schrieb Noralf Trønnes: >> >> >> Den 25.10.2019 12.12, skrev Thomas Zimmermann: >>> Hi >>> >>> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>>> >>>>> Hi >>>>> >>>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>>> object functions in later patches. >>>>>>> >>>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>>> --- >>>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>>> 1 file changed, 34 insertions(+) >>>>>>> >>>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>>> @@ -11,6 +11,8 @@ >>>>>>> >>>>>>> #include "udl_drv.h" >>>>>>> >>>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>>> + >>>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>>> size_t size) >>>>>>> { >>>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>>> return NULL; >>>>>>> } >>>>>>> >>>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>>> return obj; >>>>>>> } >>>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>>> mutex_unlock(&udl->gem_lock); >>>>>>> return ret; >>>>>>> } >>>>>>> + >>>>>>> +/* >>>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>>> + */ >>>>>>> + >>>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>>> +{ >>>>>>> + udl_gem_free_object(obj); >>>>>>> +} >>>>>>> + >>>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>>> +{ >>>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>>> + int ret; >>>>>>> + >>>>>>> + ret = udl_gem_vmap(uobj); >>>>>>> + if (ret) >>>>>>> + return ERR_PTR(ret); >>>>>>> + return uobj->vmapping; >>>>>>> +} >>>>>>> + >>>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>>> +{ >>>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>>> +} >>>>>>> + >>>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>>> + .free = udl_gem_object_free, >>>>>>> + .vmap = udl_gem_object_vmap, >>>>>>> + .vunmap = udl_gem_object_vunmap, >>>>>> >>>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>>> >>>>> I see. Should have thought of that... >>>>> >>>>>> say simpler to first cut over to shmem helpers. >>>>> >>>>> Right. I was already attempting the conversion and the udl gem is more >>>>> or less the same as shmem, except for the flags field. [1] The flag >>>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>>> always maps with writecombining. >>>>> >>>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>>> kind of optimization. Do you have an idea? >>>>> >>>>> Best regards >>>>> Thomas >>>>> >>>>> [1] >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>>> [2] >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>>> >>>> udl doesn't set prefer_shadow = 1, which means compositors will render >>>> directly into the buffer. And for that you want caching. For imported >>>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>>> (and that would probably be faster than going with wc for everything). >>>> So we do want cachable, it's going to suck otherwise. >>> >>> Thanks for clarifying. Actually, it does have these calls in its dirty >>> handler. [1] >>> >>>> >>>> But that should be fairly easy to do by overwriting the obj->mmap >>>> callback and wrapping it around the shmem one. >>> >>> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >>> Could this be added? >>> >> >> I had a flag to set this in the initial version of the shmem helper >> modeled after udl, but Thomas Hellstrom brought up a question and it was >> dropped. The issue was beyond my understanding: >> >> [PATCH v3 0/2] drm: Add shmem GEM library >> https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html > > If I understand that discussion correctly, the concern was that write > combining and shared memory would not work well together. So you went > with always-cached? > > Just recently, Gerd added unconditional write combining in rev 0be8958936. > I don't remember, Rob picked up the patch since I couldn't use shmem after all for tinydrm. I see in the commit message that he made this change: v7: - Use write-combine for mmap instead. This is the more common case. (robher) Then we have this: drm/gem_shmem: Use a writecombine mapping for ->vaddr (be7d9f05c53e) So it looks like my initial work has been fixed up piece by piece to use writecombine. Noralf. > Best regards > Thomas > >> >> In tinydrm I have sped up uncached writes on arm by copying one pixel >> line at a time into a temporary buffer before accessing the individual >> bytes. See drm_fb_swab16(). >> >> Noralf. >> >>> (I'm just trying to understand the available options here before >>> attempting to do a conversion.) >>> >>> Best regards >>> Thomas >>> >>>> >>>> What surprises me more is that udl supports mmap on imported dma-buf, >>>> that's some real quirky stuff. Not sure there's really other drivers >>>> doing that. Might be easier to rip that out :-) >>>> -Daniel >>>> >>> >>> [1] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >>> >>> >>> >>> _______________________________________________ >>> dri-devel mailing list >>> dri-devel@lists.freedesktop.org >>> https://lists.freedesktop.org/mailman/listinfo/dri-devel >>> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() @ 2019-10-25 13:44 ` Noralf Trønnes 0 siblings, 0 replies; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 13:44 UTC (permalink / raw) To: Thomas Zimmermann, Daniel Vetter Cc: Dave Airlie, Sean Paul, dri-devel, Sam Ravnborg, Gerd Hoffmann Den 25.10.2019 14.20, skrev Thomas Zimmermann: > (cc: Gerd) > > Hi > > Am 25.10.19 um 13:44 schrieb Noralf Trønnes: >> >> >> Den 25.10.2019 12.12, skrev Thomas Zimmermann: >>> Hi >>> >>> Am 25.10.19 um 11:28 schrieb Daniel Vetter: >>>> On Fri, Oct 25, 2019 at 9:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote >>>>> >>>>> Hi >>>>> >>>>> Am 25.10.19 um 09:40 schrieb Daniel Vetter: >>>>>> On Thu, Oct 24, 2019 at 04:42:35PM +0200, Thomas Zimmermann wrote: >>>>>>> Implementing vmap() and vunmap() of struct drm_gem_object_funcs is >>>>>>> required by generic fbdev emulation. Supporting free() is easy as >>>>>>> well. More udl-specific interfaces can probably be replaced by GEM >>>>>>> object functions in later patches. >>>>>>> >>>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>>>>> --- >>>>>>> drivers/gpu/drm/udl/udl_gem.c | 34 ++++++++++++++++++++++++++++++++++ >>>>>>> 1 file changed, 34 insertions(+) >>>>>>> >>>>>>> diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c >>>>>>> index 3ea0cd9ae2d6..6ca097c270d6 100644 >>>>>>> --- a/drivers/gpu/drm/udl/udl_gem.c >>>>>>> +++ b/drivers/gpu/drm/udl/udl_gem.c >>>>>>> @@ -11,6 +11,8 @@ >>>>>>> >>>>>>> #include "udl_drv.h" >>>>>>> >>>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs; >>>>>>> + >>>>>>> struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>>> size_t size) >>>>>>> { >>>>>>> @@ -25,6 +27,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, >>>>>>> return NULL; >>>>>>> } >>>>>>> >>>>>>> + obj->base.funcs = &udl_gem_object_funcs; >>>>>>> obj->flags = UDL_BO_CACHEABLE; >>>>>>> return obj; >>>>>>> } >>>>>>> @@ -230,3 +233,34 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, >>>>>>> mutex_unlock(&udl->gem_lock); >>>>>>> return ret; >>>>>>> } >>>>>>> + >>>>>>> +/* >>>>>>> + * Helpers for struct drm_gem_object_funcs >>>>>>> + */ >>>>>>> + >>>>>>> +static void udl_gem_object_free(struct drm_gem_object *obj) >>>>>>> +{ >>>>>>> + udl_gem_free_object(obj); >>>>>>> +} >>>>>>> + >>>>>>> +static void *udl_gem_object_vmap(struct drm_gem_object *obj) >>>>>>> +{ >>>>>>> + struct udl_gem_object *uobj = to_udl_bo(obj); >>>>>>> + int ret; >>>>>>> + >>>>>>> + ret = udl_gem_vmap(uobj); >>>>>>> + if (ret) >>>>>>> + return ERR_PTR(ret); >>>>>>> + return uobj->vmapping; >>>>>>> +} >>>>>>> + >>>>>>> +static void udl_gem_object_vunmap(struct drm_gem_object *obj, void *vaddr) >>>>>>> +{ >>>>>>> + return udl_gem_vunmap(to_udl_bo(obj)); >>>>>>> +} >>>>>>> + >>>>>>> +static const struct drm_gem_object_funcs udl_gem_object_funcs = { >>>>>>> + .free = udl_gem_object_free, >>>>>>> + .vmap = udl_gem_object_vmap, >>>>>>> + .vunmap = udl_gem_object_vunmap, >>>>>> >>>>>> Yeah this doesn't work, you need to refcount the vmap here I think. I'd >>>>> >>>>> I see. Should have thought of that... >>>>> >>>>>> say simpler to first cut over to shmem helpers. >>>>> >>>>> Right. I was already attempting the conversion and the udl gem is more >>>>> or less the same as shmem, except for the flags field. [1] The flag >>>>> signals page attributes for mmap-ing [2]. For prime-imported BOs its is >>>>> set to writecombining, and for local BOs it is set to cached. Shmem >>>>> always maps with writecombining. >>>>> >>>>> I don't see why udl BOs are special wrt to mmap-ing. It seems to be some >>>>> kind of optimization. Do you have an idea? >>>>> >>>>> Best regards >>>>> Thomas >>>>> >>>>> [1] >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_drv.h?h=v5.3#n78 >>>>> [2] >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_gem.c?h=v5.3#n57 >>>> >>>> udl doesn't set prefer_shadow = 1, which means compositors will render >>>> directly into the buffer. And for that you want caching. For imported >>>> dma-buf otoh you want wc to make sure it's coherent. Otherwise I guess >>>> udl would need to get the dma_buf_begin/end_cpu_access calls added >>>> (and that would probably be faster than going with wc for everything). >>>> So we do want cachable, it's going to suck otherwise. >>> >>> Thanks for clarifying. Actually, it does have these calls in its dirty >>> handler. [1] >>> >>>> >>>> But that should be fairly easy to do by overwriting the obj->mmap >>>> callback and wrapping it around the shmem one. >>> >>> Is there a reason why shmem doesn't implement the wc-vs.cached logic? >>> Could this be added? >>> >> >> I had a flag to set this in the initial version of the shmem helper >> modeled after udl, but Thomas Hellstrom brought up a question and it was >> dropped. The issue was beyond my understanding: >> >> [PATCH v3 0/2] drm: Add shmem GEM library >> https://lists.freedesktop.org/archives/dri-devel/2018-September/190001.html > > If I understand that discussion correctly, the concern was that write > combining and shared memory would not work well together. So you went > with always-cached? > > Just recently, Gerd added unconditional write combining in rev 0be8958936. > I don't remember, Rob picked up the patch since I couldn't use shmem after all for tinydrm. I see in the commit message that he made this change: v7: - Use write-combine for mmap instead. This is the more common case. (robher) Then we have this: drm/gem_shmem: Use a writecombine mapping for ->vaddr (be7d9f05c53e) So it looks like my initial work has been fixed up piece by piece to use writecombine. Noralf. > Best regards > Thomas > >> >> In tinydrm I have sped up uncached writes on arm by copying one pixel >> line at a time into a temporary buffer before accessing the individual >> bytes. See drm_fb_swab16(). >> >> Noralf. >> >>> (I'm just trying to understand the available options here before >>> attempting to do a conversion.) >>> >>> Best regards >>> Thomas >>> >>>> >>>> What surprises me more is that udl supports mmap on imported dma-buf, >>>> that's some real quirky stuff. Not sure there's really other drivers >>>> doing that. Might be easier to rip that out :-) >>>> -Daniel >>>> >>> >>> [1] >>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/udl/udl_fb.c?h=v5.3#n293 >>> >>> >>> >>> _______________________________________________ >>> dri-devel mailing list >>> dri-devel@lists.freedesktop.org >>> https://lists.freedesktop.org/mailman/listinfo/dri-devel >>> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 4/5] drm/udl: Map BO memory pages in unencrypted mode 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann ` (2 preceding siblings ...) 2019-10-24 14:42 ` [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() Thomas Zimmermann @ 2019-10-24 14:42 ` Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation Thomas Zimmermann 4 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw) To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel The udl driver's fbdev code maps pages in unencrypted mode. To switch over to generic fbdev emulation, we set this flag in the BO mapping code. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/udl/udl_gem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 6ca097c270d6..68e4757e83f5 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -100,6 +100,9 @@ int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) update_vm_cache_attr(to_udl_bo(vma->vm_private_data), vma); + /* We don't want the framebuffer to be mapped encrypted */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); + return ret; } @@ -158,7 +161,7 @@ int udl_gem_vmap(struct udl_gem_object *obj) return -ENOMEM; return 0; } - + ret = udl_gem_get_pages(obj); if (ret) return ret; -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann ` (3 preceding siblings ...) 2019-10-24 14:42 ` [PATCH 4/5] drm/udl: Map BO memory pages in unencrypted mode Thomas Zimmermann @ 2019-10-24 14:42 ` Thomas Zimmermann 2019-10-25 7:47 ` Daniel Vetter 4 siblings, 1 reply; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-24 14:42 UTC (permalink / raw) To: airlied, sean, daniel, sam, noralf; +Cc: Thomas Zimmermann, dri-devel Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/udl/udl_drv.c | 3 + drivers/gpu/drm/udl/udl_drv.h | 4 - drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- drivers/gpu/drm/udl/udl_main.c | 2 - drivers/gpu/drm/udl/udl_modeset.c | 3 +- 5 files changed, 8 insertions(+), 267 deletions(-) diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 15ad7a338f9d..6beaa1109c2c 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -7,6 +7,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_probe_helper.h> @@ -62,6 +63,8 @@ static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM, .release = udl_driver_release, + .lastclose = drm_fb_helper_lastclose, + /* gem hooks */ .gem_free_object_unlocked = udl_gem_free_object, .gem_vm_ops = &udl_gem_vm_ops, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 12a970fd9a87..5f8a7ac084f6 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -50,8 +50,6 @@ struct urb_list { size_t size; }; -struct udl_fbdev; - struct udl_device { struct drm_device drm; struct device *dev; @@ -65,7 +63,6 @@ struct udl_device { struct urb_list urbs; atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ - struct udl_fbdev *fbdev; char mode_buf[1024]; uint32_t mode_buf_len; atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); void udl_fini(struct drm_device *dev); int udl_fbdev_init(struct drm_device *dev); -void udl_fbdev_cleanup(struct drm_device *dev); void udl_fbdev_unplug(struct drm_device *dev); struct drm_framebuffer * udl_fb_user_fb_create(struct drm_device *dev, diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index ef3504d06343..43a1da3a56c3 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -19,19 +19,9 @@ #include "udl_drv.h" -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ - -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ static int fb_bpp = 16; module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); - -struct udl_fbdev { - struct drm_fb_helper helper; /* must be first */ - struct udl_framebuffer ufb; - int fb_count; -}; #define DL_ALIGN_UP(x, a) ALIGN(x, a) #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) @@ -157,123 +147,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, return 0; } -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long offset; - unsigned long page, pos; - - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - - offset = vma->vm_pgoff << PAGE_SHIFT; - - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) - return -EINVAL; - - pos = (unsigned long)info->fix.smem_start + offset; - - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", - pos, size); - - /* We don't want the framebuffer to be mapped encrypted */ - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); - - while (size > 0) { - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ - return 0; -} - -/* - * It's common for several clients to have framebuffer open simultaneously. - * e.g. both fbcon and X. Makes things interesting. - * Assumes caller is holding info->lock (for open and release at least) - */ -static int udl_fb_open(struct fb_info *info, int user) -{ - struct udl_fbdev *ufbdev = info->par; - struct drm_device *dev = ufbdev->ufb.base.dev; - struct udl_device *udl = to_udl(dev); - - /* If the USB device is gone, we don't accept new opens */ - if (drm_dev_is_unplugged(&udl->drm)) - return -ENODEV; - - ufbdev->fb_count++; - -#ifdef CONFIG_DRM_FBDEV_EMULATION - if (fb_defio && (info->fbdefio == NULL)) { - /* enable defio at last moment if not disabled by client */ - - struct fb_deferred_io *fbdefio; - - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); - - if (fbdefio) { - fbdefio->delay = DL_DEFIO_WRITE_DELAY; - fbdefio->deferred_io = drm_fb_helper_deferred_io; - } - - info->fbdefio = fbdefio; - fb_deferred_io_init(info); - } -#endif - - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", - info->node, user, info, ufbdev->fb_count); - - return 0; -} - - -/* - * Assumes caller is holding info->lock mutex (for open and release at least) - */ -static int udl_fb_release(struct fb_info *info, int user) -{ - struct udl_fbdev *ufbdev = info->par; - - ufbdev->fb_count--; - -#ifdef CONFIG_DRM_FBDEV_EMULATION - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { - fb_deferred_io_cleanup(info); - kfree(info->fbdefio); - info->fbdefio = NULL; - info->fbops->fb_mmap = udl_fb_mmap; - } -#endif - - pr_debug("released /dev/fb%d user=%d count=%d\n", - info->node, user, ufbdev->fb_count); - - return 0; -} - -static struct fb_ops udlfb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_fillrect = drm_fb_helper_sys_fillrect, - .fb_copyarea = drm_fb_helper_sys_copyarea, - .fb_imageblit = drm_fb_helper_sys_imageblit, - .fb_mmap = udl_fb_mmap, - .fb_open = udl_fb_open, - .fb_release = udl_fb_release, -}; - static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, struct drm_file *file, unsigned flags, unsigned color, @@ -346,150 +219,20 @@ udl_framebuffer_init(struct drm_device *dev, return ret; } - -static int udlfb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct udl_fbdev *ufbdev = - container_of(helper, struct udl_fbdev, helper); - struct drm_device *dev = ufbdev->helper.dev; - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd; - struct udl_gem_object *obj; - uint32_t size; - int ret = 0; - - if (sizes->surface_bpp == 24) - sizes->surface_bpp = 32; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - size = mode_cmd.pitches[0] * mode_cmd.height; - size = ALIGN(size, PAGE_SIZE); - - obj = udl_gem_alloc_object(dev, size); - if (!obj) - goto out; - - ret = udl_gem_vmap(obj); - if (ret) { - DRM_ERROR("failed to vmap fb\n"); - goto out_gfree; - } - - info = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto out_gfree; - } - - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); - if (ret) - goto out_gfree; - - fb = &ufbdev->ufb.base; - - ufbdev->helper.fb = fb; - - info->screen_base = ufbdev->ufb.obj->vmapping; - info->fix.smem_len = size; - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; - - info->fbops = &udlfb_ops; - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); - - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", - fb->width, fb->height, - ufbdev->ufb.obj->vmapping); - - return ret; -out_gfree: - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); -out: - return ret; -} - -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { - .fb_probe = udlfb_create, -}; - -static void udl_fbdev_destroy(struct drm_device *dev, - struct udl_fbdev *ufbdev) -{ - drm_fb_helper_unregister_fbi(&ufbdev->helper); - drm_fb_helper_fini(&ufbdev->helper); - if (ufbdev->ufb.obj) { - drm_framebuffer_unregister_private(&ufbdev->ufb.base); - drm_framebuffer_cleanup(&ufbdev->ufb.base); - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); - } -} - int udl_fbdev_init(struct drm_device *dev) { - struct udl_device *udl = to_udl(dev); int bpp_sel = fb_bpp; - struct udl_fbdev *ufbdev; int ret; - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); - if (!ufbdev) - return -ENOMEM; - - udl->fbdev = ufbdev; - - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); - - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); - if (ret) - goto free; - - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); + ret = drm_fbdev_generic_setup(dev, bpp_sel); if (ret) - goto fini; - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); - if (ret) - goto fini; - + return ret; return 0; - -fini: - drm_fb_helper_fini(&ufbdev->helper); -free: - kfree(ufbdev); - return ret; -} - -void udl_fbdev_cleanup(struct drm_device *dev) -{ - struct udl_device *udl = to_udl(dev); - if (!udl->fbdev) - return; - - udl_fbdev_destroy(dev, udl->fbdev); - kfree(udl->fbdev); - udl->fbdev = NULL; } void udl_fbdev_unplug(struct drm_device *dev) { - struct udl_device *udl = to_udl(dev); - struct udl_fbdev *ufbdev; - if (!udl->fbdev) - return; - - ufbdev = udl->fbdev; - drm_fb_helper_unlink_fbi(&ufbdev->helper); + drm_fb_helper_unlink_fbi(dev->fb_helper); } struct drm_framebuffer * diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 4e854e017390..2a6399290f09 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -367,6 +367,4 @@ void udl_fini(struct drm_device *dev) if (udl->urbs.count) udl_free_urb_list(dev); - - udl_fbdev_cleanup(dev); } diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index bc1ab6060dc6..1517d5e881b8 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -10,6 +10,7 @@ */ #include <drm/drm_crtc_helper.h> +#include <drm/drm_fb_helper.h> #include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_vblank.h> @@ -422,7 +423,7 @@ static int udl_crtc_init(struct drm_device *dev) static const struct drm_mode_config_funcs udl_mode_funcs = { .fb_create = udl_fb_user_fb_create, - .output_poll_changed = NULL, + .output_poll_changed = drm_fb_helper_output_poll_changed, }; int udl_modeset_init(struct drm_device *dev) -- 2.23.0 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-24 14:42 ` [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation Thomas Zimmermann @ 2019-10-25 7:47 ` Daniel Vetter 2019-10-25 8:00 ` Daniel Vetter 2019-10-25 8:08 ` Thomas Zimmermann 0 siblings, 2 replies; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 7:47 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: sean, dri-devel, airlied, sam On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > --- > drivers/gpu/drm/udl/udl_drv.c | 3 + > drivers/gpu/drm/udl/udl_drv.h | 4 - > drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- > drivers/gpu/drm/udl/udl_main.c | 2 - > drivers/gpu/drm/udl/udl_modeset.c | 3 +- > 5 files changed, 8 insertions(+), 267 deletions(-) > > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c > index 15ad7a338f9d..6beaa1109c2c 100644 > --- a/drivers/gpu/drm/udl/udl_drv.c > +++ b/drivers/gpu/drm/udl/udl_drv.c > @@ -7,6 +7,7 @@ > > #include <drm/drm_crtc_helper.h> > #include <drm/drm_drv.h> > +#include <drm/drm_fb_helper.h> > #include <drm/drm_file.h> > #include <drm/drm_ioctl.h> > #include <drm/drm_probe_helper.h> > @@ -62,6 +63,8 @@ static struct drm_driver driver = { > .driver_features = DRIVER_MODESET | DRIVER_GEM, > .release = udl_driver_release, > > + .lastclose = drm_fb_helper_lastclose, > + > /* gem hooks */ > .gem_free_object_unlocked = udl_gem_free_object, > .gem_vm_ops = &udl_gem_vm_ops, > diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h > index 12a970fd9a87..5f8a7ac084f6 100644 > --- a/drivers/gpu/drm/udl/udl_drv.h > +++ b/drivers/gpu/drm/udl/udl_drv.h > @@ -50,8 +50,6 @@ struct urb_list { > size_t size; > }; > > -struct udl_fbdev; > - > struct udl_device { > struct drm_device drm; > struct device *dev; > @@ -65,7 +63,6 @@ struct udl_device { > struct urb_list urbs; > atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ > > - struct udl_fbdev *fbdev; > char mode_buf[1024]; > uint32_t mode_buf_len; > atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ > @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); > void udl_fini(struct drm_device *dev); > > int udl_fbdev_init(struct drm_device *dev); > -void udl_fbdev_cleanup(struct drm_device *dev); > void udl_fbdev_unplug(struct drm_device *dev); > struct drm_framebuffer * > udl_fb_user_fb_create(struct drm_device *dev, > diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c > index ef3504d06343..43a1da3a56c3 100644 > --- a/drivers/gpu/drm/udl/udl_fb.c > +++ b/drivers/gpu/drm/udl/udl_fb.c > @@ -19,19 +19,9 @@ > > #include "udl_drv.h" > > -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ > - > -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ > static int fb_bpp = 16; > > module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > - > -struct udl_fbdev { > - struct drm_fb_helper helper; /* must be first */ > - struct udl_framebuffer ufb; > - int fb_count; > -}; > > #define DL_ALIGN_UP(x, a) ALIGN(x, a) > #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) > @@ -157,123 +147,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, > return 0; > } > > -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) > -{ > - unsigned long start = vma->vm_start; > - unsigned long size = vma->vm_end - vma->vm_start; > - unsigned long offset; > - unsigned long page, pos; > - > - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) > - return -EINVAL; > - > - offset = vma->vm_pgoff << PAGE_SHIFT; > - > - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) > - return -EINVAL; > - > - pos = (unsigned long)info->fix.smem_start + offset; > - > - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", > - pos, size); > - > - /* We don't want the framebuffer to be mapped encrypted */ > - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); > - > - while (size > 0) { > - page = vmalloc_to_pfn((void *)pos); > - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) > - return -EAGAIN; > - > - start += PAGE_SIZE; > - pos += PAGE_SIZE; > - if (size > PAGE_SIZE) > - size -= PAGE_SIZE; > - else > - size = 0; > - } > - > - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ > - return 0; > -} > - > -/* > - * It's common for several clients to have framebuffer open simultaneously. > - * e.g. both fbcon and X. Makes things interesting. > - * Assumes caller is holding info->lock (for open and release at least) > - */ > -static int udl_fb_open(struct fb_info *info, int user) > -{ > - struct udl_fbdev *ufbdev = info->par; > - struct drm_device *dev = ufbdev->ufb.base.dev; > - struct udl_device *udl = to_udl(dev); > - > - /* If the USB device is gone, we don't accept new opens */ > - if (drm_dev_is_unplugged(&udl->drm)) > - return -ENODEV; > - > - ufbdev->fb_count++; > - > -#ifdef CONFIG_DRM_FBDEV_EMULATION > - if (fb_defio && (info->fbdefio == NULL)) { > - /* enable defio at last moment if not disabled by client */ > - > - struct fb_deferred_io *fbdefio; > - > - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); > - > - if (fbdefio) { > - fbdefio->delay = DL_DEFIO_WRITE_DELAY; > - fbdefio->deferred_io = drm_fb_helper_deferred_io; > - } > - > - info->fbdefio = fbdefio; > - fb_deferred_io_init(info); > - } > -#endif > - > - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", > - info->node, user, info, ufbdev->fb_count); > - > - return 0; > -} > - > - > -/* > - * Assumes caller is holding info->lock mutex (for open and release at least) > - */ > -static int udl_fb_release(struct fb_info *info, int user) > -{ > - struct udl_fbdev *ufbdev = info->par; > - > - ufbdev->fb_count--; > - > -#ifdef CONFIG_DRM_FBDEV_EMULATION > - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { > - fb_deferred_io_cleanup(info); > - kfree(info->fbdefio); > - info->fbdefio = NULL; > - info->fbops->fb_mmap = udl_fb_mmap; > - } > -#endif > - > - pr_debug("released /dev/fb%d user=%d count=%d\n", > - info->node, user, ufbdev->fb_count); > - > - return 0; > -} > - > -static struct fb_ops udlfb_ops = { > - .owner = THIS_MODULE, > - DRM_FB_HELPER_DEFAULT_OPS, > - .fb_fillrect = drm_fb_helper_sys_fillrect, > - .fb_copyarea = drm_fb_helper_sys_copyarea, > - .fb_imageblit = drm_fb_helper_sys_imageblit, > - .fb_mmap = udl_fb_mmap, > - .fb_open = udl_fb_open, > - .fb_release = udl_fb_release, > -}; > - > static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, > struct drm_file *file, > unsigned flags, unsigned color, > @@ -346,150 +219,20 @@ udl_framebuffer_init(struct drm_device *dev, > return ret; > } > > - > -static int udlfb_create(struct drm_fb_helper *helper, > - struct drm_fb_helper_surface_size *sizes) > -{ > - struct udl_fbdev *ufbdev = > - container_of(helper, struct udl_fbdev, helper); > - struct drm_device *dev = ufbdev->helper.dev; > - struct fb_info *info; > - struct drm_framebuffer *fb; > - struct drm_mode_fb_cmd2 mode_cmd; > - struct udl_gem_object *obj; > - uint32_t size; > - int ret = 0; > - > - if (sizes->surface_bpp == 24) > - sizes->surface_bpp = 32; > - > - mode_cmd.width = sizes->surface_width; > - mode_cmd.height = sizes->surface_height; > - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); > - > - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > - sizes->surface_depth); > - > - size = mode_cmd.pitches[0] * mode_cmd.height; > - size = ALIGN(size, PAGE_SIZE); > - > - obj = udl_gem_alloc_object(dev, size); > - if (!obj) > - goto out; > - > - ret = udl_gem_vmap(obj); > - if (ret) { > - DRM_ERROR("failed to vmap fb\n"); > - goto out_gfree; > - } > - > - info = drm_fb_helper_alloc_fbi(helper); > - if (IS_ERR(info)) { > - ret = PTR_ERR(info); > - goto out_gfree; > - } > - > - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); > - if (ret) > - goto out_gfree; > - > - fb = &ufbdev->ufb.base; > - > - ufbdev->helper.fb = fb; > - > - info->screen_base = ufbdev->ufb.obj->vmapping; > - info->fix.smem_len = size; > - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; > - > - info->fbops = &udlfb_ops; > - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); > - > - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", > - fb->width, fb->height, > - ufbdev->ufb.obj->vmapping); > - > - return ret; > -out_gfree: > - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > -out: > - return ret; > -} > - > -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { > - .fb_probe = udlfb_create, > -}; > - > -static void udl_fbdev_destroy(struct drm_device *dev, > - struct udl_fbdev *ufbdev) > -{ > - drm_fb_helper_unregister_fbi(&ufbdev->helper); > - drm_fb_helper_fini(&ufbdev->helper); > - if (ufbdev->ufb.obj) { > - drm_framebuffer_unregister_private(&ufbdev->ufb.base); > - drm_framebuffer_cleanup(&ufbdev->ufb.base); > - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > - } > -} > - > int udl_fbdev_init(struct drm_device *dev) > { > - struct udl_device *udl = to_udl(dev); > int bpp_sel = fb_bpp; > - struct udl_fbdev *ufbdev; > int ret; > > - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); > - if (!ufbdev) > - return -ENOMEM; > - > - udl->fbdev = ufbdev; > - > - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); > - > - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); > - if (ret) > - goto free; > - > - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); > + ret = drm_fbdev_generic_setup(dev, bpp_sel); > if (ret) > - goto fini; > - > - /* disable all the possible outputs/crtcs before entering KMS mode */ > - drm_helper_disable_unused_functions(dev); > - > - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); > - if (ret) > - goto fini; > - > + return ret; > return 0; > - > -fini: > - drm_fb_helper_fini(&ufbdev->helper); > -free: > - kfree(ufbdev); > - return ret; > -} > - > -void udl_fbdev_cleanup(struct drm_device *dev) > -{ > - struct udl_device *udl = to_udl(dev); > - if (!udl->fbdev) > - return; > - > - udl_fbdev_destroy(dev, udl->fbdev); > - kfree(udl->fbdev); > - udl->fbdev = NULL; > } > > void udl_fbdev_unplug(struct drm_device *dev) > { > - struct udl_device *udl = to_udl(dev); > - struct udl_fbdev *ufbdev; > - if (!udl->fbdev) > - return; > - > - ufbdev = udl->fbdev; > - drm_fb_helper_unlink_fbi(&ufbdev->helper); > + drm_fb_helper_unlink_fbi(dev->fb_helper); Uh I think this here can be all garbage-collected. The generic fbdev already calls drm_fb_helper_unregister_fbi, which calls unregister_framebuffer, which is a strict superset of unlink_framebuffer. The later isn't really enough for hotunplug. So for generic fbdev you really shouldn't need any cleanup nor unplug functions anymore. Also udl is the only caller of drm_fb_helper_unlink_fbi, so we could drop that. Which removes the only external caller of unlink_framebuffer, so we can drop that too. Care to follow up with those 2 patches? Aside from this this patch here looks great! -Daniel > } > > struct drm_framebuffer * > diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c > index 4e854e017390..2a6399290f09 100644 > --- a/drivers/gpu/drm/udl/udl_main.c > +++ b/drivers/gpu/drm/udl/udl_main.c > @@ -367,6 +367,4 @@ void udl_fini(struct drm_device *dev) > > if (udl->urbs.count) > udl_free_urb_list(dev); > - > - udl_fbdev_cleanup(dev); > } > diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c > index bc1ab6060dc6..1517d5e881b8 100644 > --- a/drivers/gpu/drm/udl/udl_modeset.c > +++ b/drivers/gpu/drm/udl/udl_modeset.c > @@ -10,6 +10,7 @@ > */ > > #include <drm/drm_crtc_helper.h> > +#include <drm/drm_fb_helper.h> > #include <drm/drm_modeset_helper_vtables.h> > #include <drm/drm_vblank.h> > > @@ -422,7 +423,7 @@ static int udl_crtc_init(struct drm_device *dev) > > static const struct drm_mode_config_funcs udl_mode_funcs = { > .fb_create = udl_fb_user_fb_create, > - .output_poll_changed = NULL, > + .output_poll_changed = drm_fb_helper_output_poll_changed, > }; > > int udl_modeset_init(struct drm_device *dev) > -- > 2.23.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-25 7:47 ` Daniel Vetter @ 2019-10-25 8:00 ` Daniel Vetter 2019-10-25 11:22 ` Noralf Trønnes 2019-10-25 8:08 ` Thomas Zimmermann 1 sibling, 1 reply; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 8:00 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: sean, dri-devel, airlied, sam On Fri, Oct 25, 2019 at 09:47:46AM +0200, Daniel Vetter wrote: > On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > > --- > > drivers/gpu/drm/udl/udl_drv.c | 3 + > > drivers/gpu/drm/udl/udl_drv.h | 4 - > > drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- > > drivers/gpu/drm/udl/udl_main.c | 2 - > > drivers/gpu/drm/udl/udl_modeset.c | 3 +- > > 5 files changed, 8 insertions(+), 267 deletions(-) > > > > diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c > > index 15ad7a338f9d..6beaa1109c2c 100644 > > --- a/drivers/gpu/drm/udl/udl_drv.c > > +++ b/drivers/gpu/drm/udl/udl_drv.c > > @@ -7,6 +7,7 @@ > > > > #include <drm/drm_crtc_helper.h> > > #include <drm/drm_drv.h> > > +#include <drm/drm_fb_helper.h> > > #include <drm/drm_file.h> > > #include <drm/drm_ioctl.h> > > #include <drm/drm_probe_helper.h> > > @@ -62,6 +63,8 @@ static struct drm_driver driver = { > > .driver_features = DRIVER_MODESET | DRIVER_GEM, > > .release = udl_driver_release, > > > > + .lastclose = drm_fb_helper_lastclose, > > + > > /* gem hooks */ > > .gem_free_object_unlocked = udl_gem_free_object, > > .gem_vm_ops = &udl_gem_vm_ops, > > diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h > > index 12a970fd9a87..5f8a7ac084f6 100644 > > --- a/drivers/gpu/drm/udl/udl_drv.h > > +++ b/drivers/gpu/drm/udl/udl_drv.h > > @@ -50,8 +50,6 @@ struct urb_list { > > size_t size; > > }; > > > > -struct udl_fbdev; > > - > > struct udl_device { > > struct drm_device drm; > > struct device *dev; > > @@ -65,7 +63,6 @@ struct udl_device { > > struct urb_list urbs; > > atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ > > > > - struct udl_fbdev *fbdev; > > char mode_buf[1024]; > > uint32_t mode_buf_len; > > atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ > > @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); > > void udl_fini(struct drm_device *dev); > > > > int udl_fbdev_init(struct drm_device *dev); > > -void udl_fbdev_cleanup(struct drm_device *dev); > > void udl_fbdev_unplug(struct drm_device *dev); > > struct drm_framebuffer * > > udl_fb_user_fb_create(struct drm_device *dev, > > diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c > > index ef3504d06343..43a1da3a56c3 100644 > > --- a/drivers/gpu/drm/udl/udl_fb.c > > +++ b/drivers/gpu/drm/udl/udl_fb.c > > @@ -19,19 +19,9 @@ > > > > #include "udl_drv.h" > > > > -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ > > - > > -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ Correction on my enthusiasm, this here is a problem: The udl defio support as-is is broken, fbdev defio and shmem are fight over the page flags. Not a problem with the old code, since disabled by default. But will be a problem with the new code. I guess you didn't test fbdev mmap? We unfortunately also lack an easy igt testcase for this ... The problem is fairly tricky to solve, here's an untested idea that might work: https://dri.freedesktop.org/docs/drm/gpu/todo.html#generic-fbdev-defio-support Cheers, Daniel > > static int fb_bpp = 16; > > > > module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > > -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > > - > > -struct udl_fbdev { > > - struct drm_fb_helper helper; /* must be first */ > > - struct udl_framebuffer ufb; > > - int fb_count; > > -}; > > > > #define DL_ALIGN_UP(x, a) ALIGN(x, a) > > #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) > > @@ -157,123 +147,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, > > return 0; > > } > > > > -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) > > -{ > > - unsigned long start = vma->vm_start; > > - unsigned long size = vma->vm_end - vma->vm_start; > > - unsigned long offset; > > - unsigned long page, pos; > > - > > - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) > > - return -EINVAL; > > - > > - offset = vma->vm_pgoff << PAGE_SHIFT; > > - > > - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) > > - return -EINVAL; > > - > > - pos = (unsigned long)info->fix.smem_start + offset; > > - > > - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", > > - pos, size); > > - > > - /* We don't want the framebuffer to be mapped encrypted */ > > - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); > > - > > - while (size > 0) { > > - page = vmalloc_to_pfn((void *)pos); > > - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) > > - return -EAGAIN; > > - > > - start += PAGE_SIZE; > > - pos += PAGE_SIZE; > > - if (size > PAGE_SIZE) > > - size -= PAGE_SIZE; > > - else > > - size = 0; > > - } > > - > > - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ > > - return 0; > > -} > > - > > -/* > > - * It's common for several clients to have framebuffer open simultaneously. > > - * e.g. both fbcon and X. Makes things interesting. > > - * Assumes caller is holding info->lock (for open and release at least) > > - */ > > -static int udl_fb_open(struct fb_info *info, int user) > > -{ > > - struct udl_fbdev *ufbdev = info->par; > > - struct drm_device *dev = ufbdev->ufb.base.dev; > > - struct udl_device *udl = to_udl(dev); > > - > > - /* If the USB device is gone, we don't accept new opens */ > > - if (drm_dev_is_unplugged(&udl->drm)) > > - return -ENODEV; > > - > > - ufbdev->fb_count++; > > - > > -#ifdef CONFIG_DRM_FBDEV_EMULATION > > - if (fb_defio && (info->fbdefio == NULL)) { > > - /* enable defio at last moment if not disabled by client */ > > - > > - struct fb_deferred_io *fbdefio; > > - > > - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); > > - > > - if (fbdefio) { > > - fbdefio->delay = DL_DEFIO_WRITE_DELAY; > > - fbdefio->deferred_io = drm_fb_helper_deferred_io; > > - } > > - > > - info->fbdefio = fbdefio; > > - fb_deferred_io_init(info); > > - } > > -#endif > > - > > - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", > > - info->node, user, info, ufbdev->fb_count); > > - > > - return 0; > > -} > > - > > - > > -/* > > - * Assumes caller is holding info->lock mutex (for open and release at least) > > - */ > > -static int udl_fb_release(struct fb_info *info, int user) > > -{ > > - struct udl_fbdev *ufbdev = info->par; > > - > > - ufbdev->fb_count--; > > - > > -#ifdef CONFIG_DRM_FBDEV_EMULATION > > - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { > > - fb_deferred_io_cleanup(info); > > - kfree(info->fbdefio); > > - info->fbdefio = NULL; > > - info->fbops->fb_mmap = udl_fb_mmap; > > - } > > -#endif > > - > > - pr_debug("released /dev/fb%d user=%d count=%d\n", > > - info->node, user, ufbdev->fb_count); > > - > > - return 0; > > -} > > - > > -static struct fb_ops udlfb_ops = { > > - .owner = THIS_MODULE, > > - DRM_FB_HELPER_DEFAULT_OPS, > > - .fb_fillrect = drm_fb_helper_sys_fillrect, > > - .fb_copyarea = drm_fb_helper_sys_copyarea, > > - .fb_imageblit = drm_fb_helper_sys_imageblit, > > - .fb_mmap = udl_fb_mmap, > > - .fb_open = udl_fb_open, > > - .fb_release = udl_fb_release, > > -}; > > - > > static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, > > struct drm_file *file, > > unsigned flags, unsigned color, > > @@ -346,150 +219,20 @@ udl_framebuffer_init(struct drm_device *dev, > > return ret; > > } > > > > - > > -static int udlfb_create(struct drm_fb_helper *helper, > > - struct drm_fb_helper_surface_size *sizes) > > -{ > > - struct udl_fbdev *ufbdev = > > - container_of(helper, struct udl_fbdev, helper); > > - struct drm_device *dev = ufbdev->helper.dev; > > - struct fb_info *info; > > - struct drm_framebuffer *fb; > > - struct drm_mode_fb_cmd2 mode_cmd; > > - struct udl_gem_object *obj; > > - uint32_t size; > > - int ret = 0; > > - > > - if (sizes->surface_bpp == 24) > > - sizes->surface_bpp = 32; > > - > > - mode_cmd.width = sizes->surface_width; > > - mode_cmd.height = sizes->surface_height; > > - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); > > - > > - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > > - sizes->surface_depth); > > - > > - size = mode_cmd.pitches[0] * mode_cmd.height; > > - size = ALIGN(size, PAGE_SIZE); > > - > > - obj = udl_gem_alloc_object(dev, size); > > - if (!obj) > > - goto out; > > - > > - ret = udl_gem_vmap(obj); > > - if (ret) { > > - DRM_ERROR("failed to vmap fb\n"); > > - goto out_gfree; > > - } > > - > > - info = drm_fb_helper_alloc_fbi(helper); > > - if (IS_ERR(info)) { > > - ret = PTR_ERR(info); > > - goto out_gfree; > > - } > > - > > - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); > > - if (ret) > > - goto out_gfree; > > - > > - fb = &ufbdev->ufb.base; > > - > > - ufbdev->helper.fb = fb; > > - > > - info->screen_base = ufbdev->ufb.obj->vmapping; > > - info->fix.smem_len = size; > > - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; > > - > > - info->fbops = &udlfb_ops; > > - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); > > - > > - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", > > - fb->width, fb->height, > > - ufbdev->ufb.obj->vmapping); > > - > > - return ret; > > -out_gfree: > > - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > > -out: > > - return ret; > > -} > > - > > -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { > > - .fb_probe = udlfb_create, > > -}; > > - > > -static void udl_fbdev_destroy(struct drm_device *dev, > > - struct udl_fbdev *ufbdev) > > -{ > > - drm_fb_helper_unregister_fbi(&ufbdev->helper); > > - drm_fb_helper_fini(&ufbdev->helper); > > - if (ufbdev->ufb.obj) { > > - drm_framebuffer_unregister_private(&ufbdev->ufb.base); > > - drm_framebuffer_cleanup(&ufbdev->ufb.base); > > - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > > - } > > -} > > - > > int udl_fbdev_init(struct drm_device *dev) > > { > > - struct udl_device *udl = to_udl(dev); > > int bpp_sel = fb_bpp; > > - struct udl_fbdev *ufbdev; > > int ret; > > > > - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); > > - if (!ufbdev) > > - return -ENOMEM; > > - > > - udl->fbdev = ufbdev; > > - > > - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); > > - > > - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); > > - if (ret) > > - goto free; > > - > > - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); > > + ret = drm_fbdev_generic_setup(dev, bpp_sel); > > if (ret) > > - goto fini; > > - > > - /* disable all the possible outputs/crtcs before entering KMS mode */ > > - drm_helper_disable_unused_functions(dev); > > - > > - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); > > - if (ret) > > - goto fini; > > - > > + return ret; > > return 0; > > - > > -fini: > > - drm_fb_helper_fini(&ufbdev->helper); > > -free: > > - kfree(ufbdev); > > - return ret; > > -} > > - > > -void udl_fbdev_cleanup(struct drm_device *dev) > > -{ > > - struct udl_device *udl = to_udl(dev); > > - if (!udl->fbdev) > > - return; > > - > > - udl_fbdev_destroy(dev, udl->fbdev); > > - kfree(udl->fbdev); > > - udl->fbdev = NULL; > > } > > > > void udl_fbdev_unplug(struct drm_device *dev) > > { > > - struct udl_device *udl = to_udl(dev); > > - struct udl_fbdev *ufbdev; > > - if (!udl->fbdev) > > - return; > > - > > - ufbdev = udl->fbdev; > > - drm_fb_helper_unlink_fbi(&ufbdev->helper); > > + drm_fb_helper_unlink_fbi(dev->fb_helper); > > Uh I think this here can be all garbage-collected. The generic fbdev > already calls drm_fb_helper_unregister_fbi, which calls > unregister_framebuffer, which is a strict superset of unlink_framebuffer. > The later isn't really enough for hotunplug. > > So for generic fbdev you really shouldn't need any cleanup nor unplug > functions anymore. > > Also udl is the only caller of drm_fb_helper_unlink_fbi, so we could drop > that. Which removes the only external caller of unlink_framebuffer, so we > can drop that too. Care to follow up with those 2 patches? > > Aside from this this patch here looks great! > -Daniel > > > } > > > > struct drm_framebuffer * > > diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c > > index 4e854e017390..2a6399290f09 100644 > > --- a/drivers/gpu/drm/udl/udl_main.c > > +++ b/drivers/gpu/drm/udl/udl_main.c > > @@ -367,6 +367,4 @@ void udl_fini(struct drm_device *dev) > > > > if (udl->urbs.count) > > udl_free_urb_list(dev); > > - > > - udl_fbdev_cleanup(dev); > > } > > diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c > > index bc1ab6060dc6..1517d5e881b8 100644 > > --- a/drivers/gpu/drm/udl/udl_modeset.c > > +++ b/drivers/gpu/drm/udl/udl_modeset.c > > @@ -10,6 +10,7 @@ > > */ > > > > #include <drm/drm_crtc_helper.h> > > +#include <drm/drm_fb_helper.h> > > #include <drm/drm_modeset_helper_vtables.h> > > #include <drm/drm_vblank.h> > > > > @@ -422,7 +423,7 @@ static int udl_crtc_init(struct drm_device *dev) > > > > static const struct drm_mode_config_funcs udl_mode_funcs = { > > .fb_create = udl_fb_user_fb_create, > > - .output_poll_changed = NULL, > > + .output_poll_changed = drm_fb_helper_output_poll_changed, > > }; > > > > int udl_modeset_init(struct drm_device *dev) > > -- > > 2.23.0 > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-25 8:00 ` Daniel Vetter @ 2019-10-25 11:22 ` Noralf Trønnes 2019-10-25 11:44 ` Thomas Zimmermann 0 siblings, 1 reply; 31+ messages in thread From: Noralf Trønnes @ 2019-10-25 11:22 UTC (permalink / raw) To: Daniel Vetter, Thomas Zimmermann; +Cc: airlied, sean, dri-devel, sam Den 25.10.2019 10.00, skrev Daniel Vetter: > On Fri, Oct 25, 2019 at 09:47:46AM +0200, Daniel Vetter wrote: >> On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: >>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>> --- >>> drivers/gpu/drm/udl/udl_drv.c | 3 + >>> drivers/gpu/drm/udl/udl_drv.h | 4 - >>> drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- >>> drivers/gpu/drm/udl/udl_main.c | 2 - >>> drivers/gpu/drm/udl/udl_modeset.c | 3 +- >>> 5 files changed, 8 insertions(+), 267 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c >>> index 15ad7a338f9d..6beaa1109c2c 100644 >>> --- a/drivers/gpu/drm/udl/udl_drv.c >>> +++ b/drivers/gpu/drm/udl/udl_drv.c >>> @@ -7,6 +7,7 @@ >>> >>> #include <drm/drm_crtc_helper.h> >>> #include <drm/drm_drv.h> >>> +#include <drm/drm_fb_helper.h> >>> #include <drm/drm_file.h> >>> #include <drm/drm_ioctl.h> >>> #include <drm/drm_probe_helper.h> >>> @@ -62,6 +63,8 @@ static struct drm_driver driver = { >>> .driver_features = DRIVER_MODESET | DRIVER_GEM, >>> .release = udl_driver_release, >>> >>> + .lastclose = drm_fb_helper_lastclose, >>> + >>> /* gem hooks */ >>> .gem_free_object_unlocked = udl_gem_free_object, >>> .gem_vm_ops = &udl_gem_vm_ops, >>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h >>> index 12a970fd9a87..5f8a7ac084f6 100644 >>> --- a/drivers/gpu/drm/udl/udl_drv.h >>> +++ b/drivers/gpu/drm/udl/udl_drv.h >>> @@ -50,8 +50,6 @@ struct urb_list { >>> size_t size; >>> }; >>> >>> -struct udl_fbdev; >>> - >>> struct udl_device { >>> struct drm_device drm; >>> struct device *dev; >>> @@ -65,7 +63,6 @@ struct udl_device { >>> struct urb_list urbs; >>> atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ >>> >>> - struct udl_fbdev *fbdev; >>> char mode_buf[1024]; >>> uint32_t mode_buf_len; >>> atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ >>> @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); >>> void udl_fini(struct drm_device *dev); >>> >>> int udl_fbdev_init(struct drm_device *dev); >>> -void udl_fbdev_cleanup(struct drm_device *dev); >>> void udl_fbdev_unplug(struct drm_device *dev); >>> struct drm_framebuffer * >>> udl_fb_user_fb_create(struct drm_device *dev, >>> diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c >>> index ef3504d06343..43a1da3a56c3 100644 >>> --- a/drivers/gpu/drm/udl/udl_fb.c >>> +++ b/drivers/gpu/drm/udl/udl_fb.c >>> @@ -19,19 +19,9 @@ >>> >>> #include "udl_drv.h" >>> >>> -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ >>> - >>> -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ > > Correction on my enthusiasm, this here is a problem: > > The udl defio support as-is is broken, fbdev defio and shmem are fight > over the page flags. Not a problem with the old code, since disabled by > default. But will be a problem with the new code. I guess you didn't test > fbdev mmap? We unfortunately also lack an easy igt testcase for this ... This is where the shadow buffer comes to the rescue. fbdev gets a vmalloc buffer and this is blitted on the shmem buffer in the defio callback before calling the framebuffer .dirty callback. So the defio internals never sees the shmem buffer. At least this worked when I was writing the shmem helper. Noralf. > > The problem is fairly tricky to solve, here's an untested idea that might > work: > > https://dri.freedesktop.org/docs/drm/gpu/todo.html#generic-fbdev-defio-support > > Cheers, Daniel > _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-25 11:22 ` Noralf Trønnes @ 2019-10-25 11:44 ` Thomas Zimmermann 0 siblings, 0 replies; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 11:44 UTC (permalink / raw) To: Noralf Trønnes, Daniel Vetter; +Cc: airlied, sean, dri-devel, sam [-- Attachment #1.1.1: Type: text/plain, Size: 4269 bytes --] Hi Noralf Am 25.10.19 um 13:22 schrieb Noralf Trønnes: > > > Den 25.10.2019 10.00, skrev Daniel Vetter: >> On Fri, Oct 25, 2019 at 09:47:46AM +0200, Daniel Vetter wrote: >>> On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: >>>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >>>> --- >>>> drivers/gpu/drm/udl/udl_drv.c | 3 + >>>> drivers/gpu/drm/udl/udl_drv.h | 4 - >>>> drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- >>>> drivers/gpu/drm/udl/udl_main.c | 2 - >>>> drivers/gpu/drm/udl/udl_modeset.c | 3 +- >>>> 5 files changed, 8 insertions(+), 267 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c >>>> index 15ad7a338f9d..6beaa1109c2c 100644 >>>> --- a/drivers/gpu/drm/udl/udl_drv.c >>>> +++ b/drivers/gpu/drm/udl/udl_drv.c >>>> @@ -7,6 +7,7 @@ >>>> >>>> #include <drm/drm_crtc_helper.h> >>>> #include <drm/drm_drv.h> >>>> +#include <drm/drm_fb_helper.h> >>>> #include <drm/drm_file.h> >>>> #include <drm/drm_ioctl.h> >>>> #include <drm/drm_probe_helper.h> >>>> @@ -62,6 +63,8 @@ static struct drm_driver driver = { >>>> .driver_features = DRIVER_MODESET | DRIVER_GEM, >>>> .release = udl_driver_release, >>>> >>>> + .lastclose = drm_fb_helper_lastclose, >>>> + >>>> /* gem hooks */ >>>> .gem_free_object_unlocked = udl_gem_free_object, >>>> .gem_vm_ops = &udl_gem_vm_ops, >>>> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h >>>> index 12a970fd9a87..5f8a7ac084f6 100644 >>>> --- a/drivers/gpu/drm/udl/udl_drv.h >>>> +++ b/drivers/gpu/drm/udl/udl_drv.h >>>> @@ -50,8 +50,6 @@ struct urb_list { >>>> size_t size; >>>> }; >>>> >>>> -struct udl_fbdev; >>>> - >>>> struct udl_device { >>>> struct drm_device drm; >>>> struct device *dev; >>>> @@ -65,7 +63,6 @@ struct udl_device { >>>> struct urb_list urbs; >>>> atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ >>>> >>>> - struct udl_fbdev *fbdev; >>>> char mode_buf[1024]; >>>> uint32_t mode_buf_len; >>>> atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ >>>> @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); >>>> void udl_fini(struct drm_device *dev); >>>> >>>> int udl_fbdev_init(struct drm_device *dev); >>>> -void udl_fbdev_cleanup(struct drm_device *dev); >>>> void udl_fbdev_unplug(struct drm_device *dev); >>>> struct drm_framebuffer * >>>> udl_fb_user_fb_create(struct drm_device *dev, >>>> diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c >>>> index ef3504d06343..43a1da3a56c3 100644 >>>> --- a/drivers/gpu/drm/udl/udl_fb.c >>>> +++ b/drivers/gpu/drm/udl/udl_fb.c >>>> @@ -19,19 +19,9 @@ >>>> >>>> #include "udl_drv.h" >>>> >>>> -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ >>>> - >>>> -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ >> >> Correction on my enthusiasm, this here is a problem: >> >> The udl defio support as-is is broken, fbdev defio and shmem are fight >> over the page flags. Not a problem with the old code, since disabled by >> default. But will be a problem with the new code. I guess you didn't test >> fbdev mmap? We unfortunately also lack an easy igt testcase for this ... > > This is where the shadow buffer comes to the rescue. fbdev gets a > vmalloc buffer and this is blitted on the shmem buffer in the defio > callback before calling the framebuffer .dirty callback. So the defio > internals never sees the shmem buffer. At least this worked when I was > writing the shmem helper. There's already a patchset on the ML, cleaning up the docs around fb defio. Please take a look. Best regards Thomas > > Noralf. > >> >> The problem is fairly tricky to solve, here's an untested idea that might >> work: >> >> https://dri.freedesktop.org/docs/drm/gpu/todo.html#generic-fbdev-defio-support >> >> Cheers, Daniel >> -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-25 7:47 ` Daniel Vetter 2019-10-25 8:00 ` Daniel Vetter @ 2019-10-25 8:08 ` Thomas Zimmermann 2019-10-25 19:10 ` Daniel Vetter 1 sibling, 1 reply; 31+ messages in thread From: Thomas Zimmermann @ 2019-10-25 8:08 UTC (permalink / raw) To: Daniel Vetter; +Cc: sam, airlied, sean, dri-devel [-- Attachment #1.1.1: Type: text/plain, Size: 13835 bytes --] Hi Am 25.10.19 um 09:47 schrieb Daniel Vetter: > On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> >> --- >> drivers/gpu/drm/udl/udl_drv.c | 3 + >> drivers/gpu/drm/udl/udl_drv.h | 4 - >> drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- >> drivers/gpu/drm/udl/udl_main.c | 2 - >> drivers/gpu/drm/udl/udl_modeset.c | 3 +- >> 5 files changed, 8 insertions(+), 267 deletions(-) >> >> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c >> index 15ad7a338f9d..6beaa1109c2c 100644 >> --- a/drivers/gpu/drm/udl/udl_drv.c >> +++ b/drivers/gpu/drm/udl/udl_drv.c >> @@ -7,6 +7,7 @@ >> >> #include <drm/drm_crtc_helper.h> >> #include <drm/drm_drv.h> >> +#include <drm/drm_fb_helper.h> >> #include <drm/drm_file.h> >> #include <drm/drm_ioctl.h> >> #include <drm/drm_probe_helper.h> >> @@ -62,6 +63,8 @@ static struct drm_driver driver = { >> .driver_features = DRIVER_MODESET | DRIVER_GEM, >> .release = udl_driver_release, >> >> + .lastclose = drm_fb_helper_lastclose, >> + >> /* gem hooks */ >> .gem_free_object_unlocked = udl_gem_free_object, >> .gem_vm_ops = &udl_gem_vm_ops, >> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h >> index 12a970fd9a87..5f8a7ac084f6 100644 >> --- a/drivers/gpu/drm/udl/udl_drv.h >> +++ b/drivers/gpu/drm/udl/udl_drv.h >> @@ -50,8 +50,6 @@ struct urb_list { >> size_t size; >> }; >> >> -struct udl_fbdev; >> - >> struct udl_device { >> struct drm_device drm; >> struct device *dev; >> @@ -65,7 +63,6 @@ struct udl_device { >> struct urb_list urbs; >> atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ >> >> - struct udl_fbdev *fbdev; >> char mode_buf[1024]; >> uint32_t mode_buf_len; >> atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ >> @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); >> void udl_fini(struct drm_device *dev); >> >> int udl_fbdev_init(struct drm_device *dev); >> -void udl_fbdev_cleanup(struct drm_device *dev); >> void udl_fbdev_unplug(struct drm_device *dev); >> struct drm_framebuffer * >> udl_fb_user_fb_create(struct drm_device *dev, >> diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c >> index ef3504d06343..43a1da3a56c3 100644 >> --- a/drivers/gpu/drm/udl/udl_fb.c >> +++ b/drivers/gpu/drm/udl/udl_fb.c >> @@ -19,19 +19,9 @@ >> >> #include "udl_drv.h" >> >> -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ >> - >> -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ >> static int fb_bpp = 16; >> >> module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); >> -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); >> - >> -struct udl_fbdev { >> - struct drm_fb_helper helper; /* must be first */ >> - struct udl_framebuffer ufb; >> - int fb_count; >> -}; >> >> #define DL_ALIGN_UP(x, a) ALIGN(x, a) >> #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) >> @@ -157,123 +147,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, >> return 0; >> } >> >> -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) >> -{ >> - unsigned long start = vma->vm_start; >> - unsigned long size = vma->vm_end - vma->vm_start; >> - unsigned long offset; >> - unsigned long page, pos; >> - >> - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) >> - return -EINVAL; >> - >> - offset = vma->vm_pgoff << PAGE_SHIFT; >> - >> - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) >> - return -EINVAL; >> - >> - pos = (unsigned long)info->fix.smem_start + offset; >> - >> - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", >> - pos, size); >> - >> - /* We don't want the framebuffer to be mapped encrypted */ >> - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); >> - >> - while (size > 0) { >> - page = vmalloc_to_pfn((void *)pos); >> - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) >> - return -EAGAIN; >> - >> - start += PAGE_SIZE; >> - pos += PAGE_SIZE; >> - if (size > PAGE_SIZE) >> - size -= PAGE_SIZE; >> - else >> - size = 0; >> - } >> - >> - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ >> - return 0; >> -} >> - >> -/* >> - * It's common for several clients to have framebuffer open simultaneously. >> - * e.g. both fbcon and X. Makes things interesting. >> - * Assumes caller is holding info->lock (for open and release at least) >> - */ >> -static int udl_fb_open(struct fb_info *info, int user) >> -{ >> - struct udl_fbdev *ufbdev = info->par; >> - struct drm_device *dev = ufbdev->ufb.base.dev; >> - struct udl_device *udl = to_udl(dev); >> - >> - /* If the USB device is gone, we don't accept new opens */ >> - if (drm_dev_is_unplugged(&udl->drm)) >> - return -ENODEV; >> - >> - ufbdev->fb_count++; >> - >> -#ifdef CONFIG_DRM_FBDEV_EMULATION >> - if (fb_defio && (info->fbdefio == NULL)) { >> - /* enable defio at last moment if not disabled by client */ >> - >> - struct fb_deferred_io *fbdefio; >> - >> - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); >> - >> - if (fbdefio) { >> - fbdefio->delay = DL_DEFIO_WRITE_DELAY; >> - fbdefio->deferred_io = drm_fb_helper_deferred_io; >> - } >> - >> - info->fbdefio = fbdefio; >> - fb_deferred_io_init(info); >> - } >> -#endif >> - >> - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", >> - info->node, user, info, ufbdev->fb_count); >> - >> - return 0; >> -} >> - >> - >> -/* >> - * Assumes caller is holding info->lock mutex (for open and release at least) >> - */ >> -static int udl_fb_release(struct fb_info *info, int user) >> -{ >> - struct udl_fbdev *ufbdev = info->par; >> - >> - ufbdev->fb_count--; >> - >> -#ifdef CONFIG_DRM_FBDEV_EMULATION >> - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { >> - fb_deferred_io_cleanup(info); >> - kfree(info->fbdefio); >> - info->fbdefio = NULL; >> - info->fbops->fb_mmap = udl_fb_mmap; >> - } >> -#endif >> - >> - pr_debug("released /dev/fb%d user=%d count=%d\n", >> - info->node, user, ufbdev->fb_count); >> - >> - return 0; >> -} >> - >> -static struct fb_ops udlfb_ops = { >> - .owner = THIS_MODULE, >> - DRM_FB_HELPER_DEFAULT_OPS, >> - .fb_fillrect = drm_fb_helper_sys_fillrect, >> - .fb_copyarea = drm_fb_helper_sys_copyarea, >> - .fb_imageblit = drm_fb_helper_sys_imageblit, >> - .fb_mmap = udl_fb_mmap, >> - .fb_open = udl_fb_open, >> - .fb_release = udl_fb_release, >> -}; >> - >> static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, >> struct drm_file *file, >> unsigned flags, unsigned color, >> @@ -346,150 +219,20 @@ udl_framebuffer_init(struct drm_device *dev, >> return ret; >> } >> >> - >> -static int udlfb_create(struct drm_fb_helper *helper, >> - struct drm_fb_helper_surface_size *sizes) >> -{ >> - struct udl_fbdev *ufbdev = >> - container_of(helper, struct udl_fbdev, helper); >> - struct drm_device *dev = ufbdev->helper.dev; >> - struct fb_info *info; >> - struct drm_framebuffer *fb; >> - struct drm_mode_fb_cmd2 mode_cmd; >> - struct udl_gem_object *obj; >> - uint32_t size; >> - int ret = 0; >> - >> - if (sizes->surface_bpp == 24) >> - sizes->surface_bpp = 32; >> - >> - mode_cmd.width = sizes->surface_width; >> - mode_cmd.height = sizes->surface_height; >> - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); >> - >> - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, >> - sizes->surface_depth); >> - >> - size = mode_cmd.pitches[0] * mode_cmd.height; >> - size = ALIGN(size, PAGE_SIZE); >> - >> - obj = udl_gem_alloc_object(dev, size); >> - if (!obj) >> - goto out; >> - >> - ret = udl_gem_vmap(obj); >> - if (ret) { >> - DRM_ERROR("failed to vmap fb\n"); >> - goto out_gfree; >> - } >> - >> - info = drm_fb_helper_alloc_fbi(helper); >> - if (IS_ERR(info)) { >> - ret = PTR_ERR(info); >> - goto out_gfree; >> - } >> - >> - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); >> - if (ret) >> - goto out_gfree; >> - >> - fb = &ufbdev->ufb.base; >> - >> - ufbdev->helper.fb = fb; >> - >> - info->screen_base = ufbdev->ufb.obj->vmapping; >> - info->fix.smem_len = size; >> - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; >> - >> - info->fbops = &udlfb_ops; >> - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); >> - >> - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", >> - fb->width, fb->height, >> - ufbdev->ufb.obj->vmapping); >> - >> - return ret; >> -out_gfree: >> - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); >> -out: >> - return ret; >> -} >> - >> -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { >> - .fb_probe = udlfb_create, >> -}; >> - >> -static void udl_fbdev_destroy(struct drm_device *dev, >> - struct udl_fbdev *ufbdev) >> -{ >> - drm_fb_helper_unregister_fbi(&ufbdev->helper); >> - drm_fb_helper_fini(&ufbdev->helper); >> - if (ufbdev->ufb.obj) { >> - drm_framebuffer_unregister_private(&ufbdev->ufb.base); >> - drm_framebuffer_cleanup(&ufbdev->ufb.base); >> - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); >> - } >> -} >> - >> int udl_fbdev_init(struct drm_device *dev) >> { >> - struct udl_device *udl = to_udl(dev); >> int bpp_sel = fb_bpp; >> - struct udl_fbdev *ufbdev; >> int ret; >> >> - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); >> - if (!ufbdev) >> - return -ENOMEM; >> - >> - udl->fbdev = ufbdev; >> - >> - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); >> - >> - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); >> - if (ret) >> - goto free; >> - >> - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); >> + ret = drm_fbdev_generic_setup(dev, bpp_sel); >> if (ret) >> - goto fini; >> - >> - /* disable all the possible outputs/crtcs before entering KMS mode */ >> - drm_helper_disable_unused_functions(dev); >> - >> - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); >> - if (ret) >> - goto fini; >> - >> + return ret; >> return 0; >> - >> -fini: >> - drm_fb_helper_fini(&ufbdev->helper); >> -free: >> - kfree(ufbdev); >> - return ret; >> -} >> - >> -void udl_fbdev_cleanup(struct drm_device *dev) >> -{ >> - struct udl_device *udl = to_udl(dev); >> - if (!udl->fbdev) >> - return; >> - >> - udl_fbdev_destroy(dev, udl->fbdev); >> - kfree(udl->fbdev); >> - udl->fbdev = NULL; >> } >> >> void udl_fbdev_unplug(struct drm_device *dev) >> { >> - struct udl_device *udl = to_udl(dev); >> - struct udl_fbdev *ufbdev; >> - if (!udl->fbdev) >> - return; >> - >> - ufbdev = udl->fbdev; >> - drm_fb_helper_unlink_fbi(&ufbdev->helper); >> + drm_fb_helper_unlink_fbi(dev->fb_helper); > > Uh I think this here can be all garbage-collected. The generic fbdev > already calls drm_fb_helper_unregister_fbi, which calls > unregister_framebuffer, which is a strict superset of unlink_framebuffer. > The later isn't really enough for hotunplug. > > So for generic fbdev you really shouldn't need any cleanup nor unplug > functions anymore. > > Also udl is the only caller of drm_fb_helper_unlink_fbi, so we could drop > that. Which removes the only external caller of unlink_framebuffer, so we > can drop that too. Care to follow up with those 2 patches? Sure. BTW is there a policy for keeping potentially useful functions? I recently converted vboxvideo to generic fbdev and notices that there are no more users of drm_fb_helper_fbdev_{setup,teardown}(). But there's still a TODO item for converting drivers over to them. Shall they remain in the code base? I have quite a few patches for udl in the making. After converting to shmem and generic fbdev, udl_framebuffer can be replaced with the GEM framebuffer code. The udl modesetting code is an epicenter of simple display pipelines. Converting this over should give atomic mode setting. Best regards Thomas > Aside from this this patch here looks great! > -Daniel > >> } >> >> struct drm_framebuffer * >> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c >> index 4e854e017390..2a6399290f09 100644 >> --- a/drivers/gpu/drm/udl/udl_main.c >> +++ b/drivers/gpu/drm/udl/udl_main.c >> @@ -367,6 +367,4 @@ void udl_fini(struct drm_device *dev) >> >> if (udl->urbs.count) >> udl_free_urb_list(dev); >> - >> - udl_fbdev_cleanup(dev); >> } >> diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c >> index bc1ab6060dc6..1517d5e881b8 100644 >> --- a/drivers/gpu/drm/udl/udl_modeset.c >> +++ b/drivers/gpu/drm/udl/udl_modeset.c >> @@ -10,6 +10,7 @@ >> */ >> >> #include <drm/drm_crtc_helper.h> >> +#include <drm/drm_fb_helper.h> >> #include <drm/drm_modeset_helper_vtables.h> >> #include <drm/drm_vblank.h> >> >> @@ -422,7 +423,7 @@ static int udl_crtc_init(struct drm_device *dev) >> >> static const struct drm_mode_config_funcs udl_mode_funcs = { >> .fb_create = udl_fb_user_fb_create, >> - .output_poll_changed = NULL, >> + .output_poll_changed = drm_fb_helper_output_poll_changed, >> }; >> >> int udl_modeset_init(struct drm_device *dev) >> -- >> 2.23.0 >> > -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Felix Imendörffer [-- Attachment #1.2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 159 bytes --] _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation 2019-10-25 8:08 ` Thomas Zimmermann @ 2019-10-25 19:10 ` Daniel Vetter 0 siblings, 0 replies; 31+ messages in thread From: Daniel Vetter @ 2019-10-25 19:10 UTC (permalink / raw) To: Thomas Zimmermann; +Cc: Sam Ravnborg, Dave Airlie, Sean Paul, dri-devel On Fri, Oct 25, 2019 at 10:08 AM Thomas Zimmermann <tzimmermann@suse.de> wrote: > > Hi > > Am 25.10.19 um 09:47 schrieb Daniel Vetter: > > On Thu, Oct 24, 2019 at 04:42:37PM +0200, Thomas Zimmermann wrote: > >> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> > >> --- > >> drivers/gpu/drm/udl/udl_drv.c | 3 + > >> drivers/gpu/drm/udl/udl_drv.h | 4 - > >> drivers/gpu/drm/udl/udl_fb.c | 263 +----------------------------- > >> drivers/gpu/drm/udl/udl_main.c | 2 - > >> drivers/gpu/drm/udl/udl_modeset.c | 3 +- > >> 5 files changed, 8 insertions(+), 267 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c > >> index 15ad7a338f9d..6beaa1109c2c 100644 > >> --- a/drivers/gpu/drm/udl/udl_drv.c > >> +++ b/drivers/gpu/drm/udl/udl_drv.c > >> @@ -7,6 +7,7 @@ > >> > >> #include <drm/drm_crtc_helper.h> > >> #include <drm/drm_drv.h> > >> +#include <drm/drm_fb_helper.h> > >> #include <drm/drm_file.h> > >> #include <drm/drm_ioctl.h> > >> #include <drm/drm_probe_helper.h> > >> @@ -62,6 +63,8 @@ static struct drm_driver driver = { > >> .driver_features = DRIVER_MODESET | DRIVER_GEM, > >> .release = udl_driver_release, > >> > >> + .lastclose = drm_fb_helper_lastclose, > >> + > >> /* gem hooks */ > >> .gem_free_object_unlocked = udl_gem_free_object, > >> .gem_vm_ops = &udl_gem_vm_ops, > >> diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h > >> index 12a970fd9a87..5f8a7ac084f6 100644 > >> --- a/drivers/gpu/drm/udl/udl_drv.h > >> +++ b/drivers/gpu/drm/udl/udl_drv.h > >> @@ -50,8 +50,6 @@ struct urb_list { > >> size_t size; > >> }; > >> > >> -struct udl_fbdev; > >> - > >> struct udl_device { > >> struct drm_device drm; > >> struct device *dev; > >> @@ -65,7 +63,6 @@ struct udl_device { > >> struct urb_list urbs; > >> atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ > >> > >> - struct udl_fbdev *fbdev; > >> char mode_buf[1024]; > >> uint32_t mode_buf_len; > >> atomic_t bytes_rendered; /* raw pixel-bytes driver asked to render */ > >> @@ -111,7 +108,6 @@ int udl_init(struct udl_device *udl); > >> void udl_fini(struct drm_device *dev); > >> > >> int udl_fbdev_init(struct drm_device *dev); > >> -void udl_fbdev_cleanup(struct drm_device *dev); > >> void udl_fbdev_unplug(struct drm_device *dev); > >> struct drm_framebuffer * > >> udl_fb_user_fb_create(struct drm_device *dev, > >> diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c > >> index ef3504d06343..43a1da3a56c3 100644 > >> --- a/drivers/gpu/drm/udl/udl_fb.c > >> +++ b/drivers/gpu/drm/udl/udl_fb.c > >> @@ -19,19 +19,9 @@ > >> > >> #include "udl_drv.h" > >> > >> -#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ > >> - > >> -static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ > >> static int fb_bpp = 16; > >> > >> module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > >> -module_param(fb_defio, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); > >> - > >> -struct udl_fbdev { > >> - struct drm_fb_helper helper; /* must be first */ > >> - struct udl_framebuffer ufb; > >> - int fb_count; > >> -}; > >> > >> #define DL_ALIGN_UP(x, a) ALIGN(x, a) > >> #define DL_ALIGN_DOWN(x, a) ALIGN_DOWN(x, a) > >> @@ -157,123 +147,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, > >> return 0; > >> } > >> > >> -static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) > >> -{ > >> - unsigned long start = vma->vm_start; > >> - unsigned long size = vma->vm_end - vma->vm_start; > >> - unsigned long offset; > >> - unsigned long page, pos; > >> - > >> - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) > >> - return -EINVAL; > >> - > >> - offset = vma->vm_pgoff << PAGE_SHIFT; > >> - > >> - if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) > >> - return -EINVAL; > >> - > >> - pos = (unsigned long)info->fix.smem_start + offset; > >> - > >> - pr_debug("mmap() framebuffer addr:%lu size:%lu\n", > >> - pos, size); > >> - > >> - /* We don't want the framebuffer to be mapped encrypted */ > >> - vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); > >> - > >> - while (size > 0) { > >> - page = vmalloc_to_pfn((void *)pos); > >> - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) > >> - return -EAGAIN; > >> - > >> - start += PAGE_SIZE; > >> - pos += PAGE_SIZE; > >> - if (size > PAGE_SIZE) > >> - size -= PAGE_SIZE; > >> - else > >> - size = 0; > >> - } > >> - > >> - /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ > >> - return 0; > >> -} > >> - > >> -/* > >> - * It's common for several clients to have framebuffer open simultaneously. > >> - * e.g. both fbcon and X. Makes things interesting. > >> - * Assumes caller is holding info->lock (for open and release at least) > >> - */ > >> -static int udl_fb_open(struct fb_info *info, int user) > >> -{ > >> - struct udl_fbdev *ufbdev = info->par; > >> - struct drm_device *dev = ufbdev->ufb.base.dev; > >> - struct udl_device *udl = to_udl(dev); > >> - > >> - /* If the USB device is gone, we don't accept new opens */ > >> - if (drm_dev_is_unplugged(&udl->drm)) > >> - return -ENODEV; > >> - > >> - ufbdev->fb_count++; > >> - > >> -#ifdef CONFIG_DRM_FBDEV_EMULATION > >> - if (fb_defio && (info->fbdefio == NULL)) { > >> - /* enable defio at last moment if not disabled by client */ > >> - > >> - struct fb_deferred_io *fbdefio; > >> - > >> - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); > >> - > >> - if (fbdefio) { > >> - fbdefio->delay = DL_DEFIO_WRITE_DELAY; > >> - fbdefio->deferred_io = drm_fb_helper_deferred_io; > >> - } > >> - > >> - info->fbdefio = fbdefio; > >> - fb_deferred_io_init(info); > >> - } > >> -#endif > >> - > >> - pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d\n", > >> - info->node, user, info, ufbdev->fb_count); > >> - > >> - return 0; > >> -} > >> - > >> - > >> -/* > >> - * Assumes caller is holding info->lock mutex (for open and release at least) > >> - */ > >> -static int udl_fb_release(struct fb_info *info, int user) > >> -{ > >> - struct udl_fbdev *ufbdev = info->par; > >> - > >> - ufbdev->fb_count--; > >> - > >> -#ifdef CONFIG_DRM_FBDEV_EMULATION > >> - if ((ufbdev->fb_count == 0) && (info->fbdefio)) { > >> - fb_deferred_io_cleanup(info); > >> - kfree(info->fbdefio); > >> - info->fbdefio = NULL; > >> - info->fbops->fb_mmap = udl_fb_mmap; > >> - } > >> -#endif > >> - > >> - pr_debug("released /dev/fb%d user=%d count=%d\n", > >> - info->node, user, ufbdev->fb_count); > >> - > >> - return 0; > >> -} > >> - > >> -static struct fb_ops udlfb_ops = { > >> - .owner = THIS_MODULE, > >> - DRM_FB_HELPER_DEFAULT_OPS, > >> - .fb_fillrect = drm_fb_helper_sys_fillrect, > >> - .fb_copyarea = drm_fb_helper_sys_copyarea, > >> - .fb_imageblit = drm_fb_helper_sys_imageblit, > >> - .fb_mmap = udl_fb_mmap, > >> - .fb_open = udl_fb_open, > >> - .fb_release = udl_fb_release, > >> -}; > >> - > >> static int udl_user_framebuffer_dirty(struct drm_framebuffer *fb, > >> struct drm_file *file, > >> unsigned flags, unsigned color, > >> @@ -346,150 +219,20 @@ udl_framebuffer_init(struct drm_device *dev, > >> return ret; > >> } > >> > >> - > >> -static int udlfb_create(struct drm_fb_helper *helper, > >> - struct drm_fb_helper_surface_size *sizes) > >> -{ > >> - struct udl_fbdev *ufbdev = > >> - container_of(helper, struct udl_fbdev, helper); > >> - struct drm_device *dev = ufbdev->helper.dev; > >> - struct fb_info *info; > >> - struct drm_framebuffer *fb; > >> - struct drm_mode_fb_cmd2 mode_cmd; > >> - struct udl_gem_object *obj; > >> - uint32_t size; > >> - int ret = 0; > >> - > >> - if (sizes->surface_bpp == 24) > >> - sizes->surface_bpp = 32; > >> - > >> - mode_cmd.width = sizes->surface_width; > >> - mode_cmd.height = sizes->surface_height; > >> - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); > >> - > >> - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, > >> - sizes->surface_depth); > >> - > >> - size = mode_cmd.pitches[0] * mode_cmd.height; > >> - size = ALIGN(size, PAGE_SIZE); > >> - > >> - obj = udl_gem_alloc_object(dev, size); > >> - if (!obj) > >> - goto out; > >> - > >> - ret = udl_gem_vmap(obj); > >> - if (ret) { > >> - DRM_ERROR("failed to vmap fb\n"); > >> - goto out_gfree; > >> - } > >> - > >> - info = drm_fb_helper_alloc_fbi(helper); > >> - if (IS_ERR(info)) { > >> - ret = PTR_ERR(info); > >> - goto out_gfree; > >> - } > >> - > >> - ret = udl_framebuffer_init(dev, &ufbdev->ufb, &mode_cmd, obj); > >> - if (ret) > >> - goto out_gfree; > >> - > >> - fb = &ufbdev->ufb.base; > >> - > >> - ufbdev->helper.fb = fb; > >> - > >> - info->screen_base = ufbdev->ufb.obj->vmapping; > >> - info->fix.smem_len = size; > >> - info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping; > >> - > >> - info->fbops = &udlfb_ops; > >> - drm_fb_helper_fill_info(info, &ufbdev->helper, sizes); > >> - > >> - DRM_DEBUG_KMS("allocated %dx%d vmal %p\n", > >> - fb->width, fb->height, > >> - ufbdev->ufb.obj->vmapping); > >> - > >> - return ret; > >> -out_gfree: > >> - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > >> -out: > >> - return ret; > >> -} > >> - > >> -static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { > >> - .fb_probe = udlfb_create, > >> -}; > >> - > >> -static void udl_fbdev_destroy(struct drm_device *dev, > >> - struct udl_fbdev *ufbdev) > >> -{ > >> - drm_fb_helper_unregister_fbi(&ufbdev->helper); > >> - drm_fb_helper_fini(&ufbdev->helper); > >> - if (ufbdev->ufb.obj) { > >> - drm_framebuffer_unregister_private(&ufbdev->ufb.base); > >> - drm_framebuffer_cleanup(&ufbdev->ufb.base); > >> - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); > >> - } > >> -} > >> - > >> int udl_fbdev_init(struct drm_device *dev) > >> { > >> - struct udl_device *udl = to_udl(dev); > >> int bpp_sel = fb_bpp; > >> - struct udl_fbdev *ufbdev; > >> int ret; > >> > >> - ufbdev = kzalloc(sizeof(struct udl_fbdev), GFP_KERNEL); > >> - if (!ufbdev) > >> - return -ENOMEM; > >> - > >> - udl->fbdev = ufbdev; > >> - > >> - drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); > >> - > >> - ret = drm_fb_helper_init(dev, &ufbdev->helper, 1); > >> - if (ret) > >> - goto free; > >> - > >> - ret = drm_fb_helper_single_add_all_connectors(&ufbdev->helper); > >> + ret = drm_fbdev_generic_setup(dev, bpp_sel); > >> if (ret) > >> - goto fini; > >> - > >> - /* disable all the possible outputs/crtcs before entering KMS mode */ > >> - drm_helper_disable_unused_functions(dev); > >> - > >> - ret = drm_fb_helper_initial_config(&ufbdev->helper, bpp_sel); > >> - if (ret) > >> - goto fini; > >> - > >> + return ret; > >> return 0; > >> - > >> -fini: > >> - drm_fb_helper_fini(&ufbdev->helper); > >> -free: > >> - kfree(ufbdev); > >> - return ret; > >> -} > >> - > >> -void udl_fbdev_cleanup(struct drm_device *dev) > >> -{ > >> - struct udl_device *udl = to_udl(dev); > >> - if (!udl->fbdev) > >> - return; > >> - > >> - udl_fbdev_destroy(dev, udl->fbdev); > >> - kfree(udl->fbdev); > >> - udl->fbdev = NULL; > >> } > >> > >> void udl_fbdev_unplug(struct drm_device *dev) > >> { > >> - struct udl_device *udl = to_udl(dev); > >> - struct udl_fbdev *ufbdev; > >> - if (!udl->fbdev) > >> - return; > >> - > >> - ufbdev = udl->fbdev; > >> - drm_fb_helper_unlink_fbi(&ufbdev->helper); > >> + drm_fb_helper_unlink_fbi(dev->fb_helper); > > > > Uh I think this here can be all garbage-collected. The generic fbdev > > already calls drm_fb_helper_unregister_fbi, which calls > > unregister_framebuffer, which is a strict superset of unlink_framebuffer. > > The later isn't really enough for hotunplug. > > > > So for generic fbdev you really shouldn't need any cleanup nor unplug > > functions anymore. > > > > Also udl is the only caller of drm_fb_helper_unlink_fbi, so we could drop > > that. Which removes the only external caller of unlink_framebuffer, so we > > can drop that too. Care to follow up with those 2 patches? > > Sure. BTW is there a policy for keeping potentially useful functions? I > recently converted vboxvideo to generic fbdev and notices that there are > no more users of drm_fb_helper_fbdev_{setup,teardown}(). But there's > still a TODO item for converting drivers over to them. Shall they remain > in the code base? As Noralf mentioned, maybe better to ditch them, and update the TODO entry to instead encourage the generic fbdev code. That one is even less code. > I have quite a few patches for udl in the making. After converting to > shmem and generic fbdev, udl_framebuffer can be replaced with the GEM > framebuffer code. The udl modesetting code is an epicenter of simple > display pipelines. Converting this over should give atomic mode setting. Awesome! -Daniel > > Best regards > Thomas > > > Aside from this this patch here looks great! > > -Daniel > > > >> } > >> > >> struct drm_framebuffer * > >> diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c > >> index 4e854e017390..2a6399290f09 100644 > >> --- a/drivers/gpu/drm/udl/udl_main.c > >> +++ b/drivers/gpu/drm/udl/udl_main.c > >> @@ -367,6 +367,4 @@ void udl_fini(struct drm_device *dev) > >> > >> if (udl->urbs.count) > >> udl_free_urb_list(dev); > >> - > >> - udl_fbdev_cleanup(dev); > >> } > >> diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c > >> index bc1ab6060dc6..1517d5e881b8 100644 > >> --- a/drivers/gpu/drm/udl/udl_modeset.c > >> +++ b/drivers/gpu/drm/udl/udl_modeset.c > >> @@ -10,6 +10,7 @@ > >> */ > >> > >> #include <drm/drm_crtc_helper.h> > >> +#include <drm/drm_fb_helper.h> > >> #include <drm/drm_modeset_helper_vtables.h> > >> #include <drm/drm_vblank.h> > >> > >> @@ -422,7 +423,7 @@ static int udl_crtc_init(struct drm_device *dev) > >> > >> static const struct drm_mode_config_funcs udl_mode_funcs = { > >> .fb_create = udl_fb_user_fb_create, > >> - .output_poll_changed = NULL, > >> + .output_poll_changed = drm_fb_helper_output_poll_changed, > >> }; > >> > >> int udl_modeset_init(struct drm_device *dev) > >> -- > >> 2.23.0 > >> > > > > -- > Thomas Zimmermann > Graphics Driver Developer > SUSE Software Solutions Germany GmbH > Maxfeldstr. 5, 90409 Nürnberg, Germany > (HRB 36809, AG Nürnberg) > Geschäftsführer: Felix Imendörffer > -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2019-10-25 19:10 UTC | newest] Thread overview: 31+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-10-24 14:42 [PATCH 0/5] drm/udl: Convert to generic fbdev emulation Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 1/5] drm/udl: Clear BO vmapping pointer after unmapping BO memory Thomas Zimmermann 2019-10-25 7:39 ` Daniel Vetter 2019-10-24 14:42 ` [PATCH 2/5] drm/udl: Set drm_driver.gem_prime_mmap Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 3/5] drm/udl: Add GEM object functions for free(), vmap(), and vunmap() Thomas Zimmermann 2019-10-25 7:40 ` Daniel Vetter 2019-10-25 7:59 ` Thomas Zimmermann 2019-10-25 7:59 ` Thomas Zimmermann 2019-10-25 9:28 ` Daniel Vetter 2019-10-25 9:28 ` Daniel Vetter 2019-10-25 10:12 ` Thomas Zimmermann 2019-10-25 10:12 ` Thomas Zimmermann 2019-10-25 11:44 ` Noralf Trønnes 2019-10-25 11:44 ` Noralf Trønnes 2019-10-25 11:47 ` Noralf Trønnes 2019-10-25 11:47 ` Noralf Trønnes 2019-10-25 12:20 ` Thomas Zimmermann 2019-10-25 12:20 ` Thomas Zimmermann 2019-10-25 13:32 ` Gerd Hoffmann 2019-10-25 14:53 ` Thomas Zimmermann 2019-10-25 14:53 ` Thomas Zimmermann 2019-10-25 13:44 ` Noralf Trønnes 2019-10-25 13:44 ` Noralf Trønnes 2019-10-24 14:42 ` [PATCH 4/5] drm/udl: Map BO memory pages in unencrypted mode Thomas Zimmermann 2019-10-24 14:42 ` [PATCH 5/5] drm/udl: Replace fbdev code with generic emulation Thomas Zimmermann 2019-10-25 7:47 ` Daniel Vetter 2019-10-25 8:00 ` Daniel Vetter 2019-10-25 11:22 ` Noralf Trønnes 2019-10-25 11:44 ` Thomas Zimmermann 2019-10-25 8:08 ` Thomas Zimmermann 2019-10-25 19:10 ` Daniel Vetter
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.