All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: noralf@tronnes.org, Javier Martinez Canillas <javierm@redhat.com>,
	dri-devel@lists.freedesktop.org,
	Maxime Ripard <mripard@kernel.org>,
	stable@kernel.org
Subject: Re: [PATCH v2 5/6] drm/gud: Use the shadow plane helper
Date: Thu, 1 Dec 2022 09:55:26 +0100	[thread overview]
Message-ID: <205fecde-723c-7c0a-e96b-6005ac43e745@suse.de> (raw)
In-Reply-To: <20221122-gud-shadow-plane-v2-5-435037990a83@tronnes.org>


[-- Attachment #1.1: Type: text/plain, Size: 7482 bytes --]



Am 30.11.22 um 20:26 schrieb Noralf Trønnes via B4 Submission Endpoint:
> From: Noralf Trønnes <noralf@tronnes.org>
> 
> Use the shadow plane helper to take care of mapping the framebuffer for
> CPU access. The synchronous flushing is now done inline without the use of
> a worker. The async path now uses a shadow buffer to hold framebuffer
> changes and it doesn't read the framebuffer behind userspace's back
> anymore.
> 
> v2:
> - Use src as variable name for iosys_map (Thomas)
> - Prepare imported buffer for CPU access in the driver (Thomas)
> 
> Signed-off-by: Noralf Trønnes <noralf@tronnes.org>

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>

> ---
>   drivers/gpu/drm/gud/gud_drv.c      |  1 +
>   drivers/gpu/drm/gud/gud_internal.h |  1 +
>   drivers/gpu/drm/gud/gud_pipe.c     | 81 ++++++++++++++++++++++++++------------
>   3 files changed, 57 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
> index d57dab104358..5aac7cda0505 100644
> --- a/drivers/gpu/drm/gud/gud_drv.c
> +++ b/drivers/gpu/drm/gud/gud_drv.c
> @@ -365,6 +365,7 @@ static void gud_debugfs_init(struct drm_minor *minor)
>   static const struct drm_simple_display_pipe_funcs gud_pipe_funcs = {
>   	.check      = gud_pipe_check,
>   	.update	    = gud_pipe_update,
> +	DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS
>   };
>   
>   static const struct drm_mode_config_funcs gud_mode_config_funcs = {
> diff --git a/drivers/gpu/drm/gud/gud_internal.h b/drivers/gpu/drm/gud/gud_internal.h
> index e351a1f1420d..0d148a6f27aa 100644
> --- a/drivers/gpu/drm/gud/gud_internal.h
> +++ b/drivers/gpu/drm/gud/gud_internal.h
> @@ -43,6 +43,7 @@ struct gud_device {
>   	struct drm_framebuffer *fb;
>   	struct drm_rect damage;
>   	bool prev_flush_failed;
> +	void *shadow_buf;
>   };
>   
>   static inline struct gud_device *to_gud_device(struct drm_device *drm)
> diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
> index 98fe8efda4a9..92189474a7ed 100644
> --- a/drivers/gpu/drm/gud/gud_pipe.c
> +++ b/drivers/gpu/drm/gud/gud_pipe.c
> @@ -358,10 +358,10 @@ static void gud_flush_damage(struct gud_device *gdrm, struct drm_framebuffer *fb
>   void gud_flush_work(struct work_struct *work)
>   {
>   	struct gud_device *gdrm = container_of(work, struct gud_device, work);
> -	struct iosys_map gem_map = { }, fb_map = { };
> +	struct iosys_map shadow_map;
>   	struct drm_framebuffer *fb;
>   	struct drm_rect damage;
> -	int idx, ret;
> +	int idx;
>   
>   	if (!drm_dev_enter(&gdrm->drm, &idx))
>   		return;
> @@ -369,6 +369,7 @@ void gud_flush_work(struct work_struct *work)
>   	mutex_lock(&gdrm->damage_lock);
>   	fb = gdrm->fb;
>   	gdrm->fb = NULL;
> +	iosys_map_set_vaddr(&shadow_map, gdrm->shadow_buf);
>   	damage = gdrm->damage;
>   	gud_clear_damage(gdrm);
>   	mutex_unlock(&gdrm->damage_lock);
> @@ -376,33 +377,33 @@ void gud_flush_work(struct work_struct *work)
>   	if (!fb)
>   		goto out;
>   
> -	ret = drm_gem_fb_vmap(fb, &gem_map, &fb_map);
> -	if (ret)
> -		goto fb_put;
> +	gud_flush_damage(gdrm, fb, &shadow_map, true, &damage);
>   
> -	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
> -	if (ret)
> -		goto vunmap;
> -
> -	/* Imported buffers are assumed to be WriteCombined with uncached reads */
> -	gud_flush_damage(gdrm, fb, &fb_map, !fb->obj[0]->import_attach, &damage);
> -
> -	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
> -vunmap:
> -	drm_gem_fb_vunmap(fb, &gem_map);
> -fb_put:
>   	drm_framebuffer_put(fb);
>   out:
>   	drm_dev_exit(idx);
>   }
>   
> -static void gud_fb_queue_damage(struct gud_device *gdrm, struct drm_framebuffer *fb,
> -				struct drm_rect *damage)
> +static int gud_fb_queue_damage(struct gud_device *gdrm, struct drm_framebuffer *fb,
> +			       const struct iosys_map *src, struct drm_rect *damage)
>   {
>   	struct drm_framebuffer *old_fb = NULL;
> +	struct iosys_map shadow_map;
>   
>   	mutex_lock(&gdrm->damage_lock);
>   
> +	if (!gdrm->shadow_buf) {
> +		gdrm->shadow_buf = vzalloc(fb->pitches[0] * fb->height);
> +		if (!gdrm->shadow_buf) {
> +			mutex_unlock(&gdrm->damage_lock);
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	iosys_map_set_vaddr(&shadow_map, gdrm->shadow_buf);
> +	iosys_map_incr(&shadow_map, drm_fb_clip_offset(fb->pitches[0], fb->format, damage));
> +	drm_fb_memcpy(&shadow_map, fb->pitches, src, fb, damage);
> +
>   	if (fb != gdrm->fb) {
>   		old_fb = gdrm->fb;
>   		drm_framebuffer_get(fb);
> @@ -420,6 +421,26 @@ static void gud_fb_queue_damage(struct gud_device *gdrm, struct drm_framebuffer
>   
>   	if (old_fb)
>   		drm_framebuffer_put(old_fb);
> +
> +	return 0;
> +}
> +
> +static void gud_fb_handle_damage(struct gud_device *gdrm, struct drm_framebuffer *fb,
> +				 const struct iosys_map *src, struct drm_rect *damage)
> +{
> +	int ret;
> +
> +	if (gdrm->flags & GUD_DISPLAY_FLAG_FULL_UPDATE)
> +		drm_rect_init(damage, 0, 0, fb->width, fb->height);
> +
> +	if (gud_async_flush) {
> +		ret = gud_fb_queue_damage(gdrm, fb, src, damage);
> +		if (ret != -ENOMEM)
> +			return;
> +	}
> +
> +	/* Imported buffers are assumed to be WriteCombined with uncached reads */
> +	gud_flush_damage(gdrm, fb, src, !fb->obj[0]->import_attach, damage);
>   }
>   
>   int gud_pipe_check(struct drm_simple_display_pipe *pipe,
> @@ -544,10 +565,11 @@ void gud_pipe_update(struct drm_simple_display_pipe *pipe,
>   	struct drm_device *drm = pipe->crtc.dev;
>   	struct gud_device *gdrm = to_gud_device(drm);
>   	struct drm_plane_state *state = pipe->plane.state;
> +	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
>   	struct drm_framebuffer *fb = state->fb;
>   	struct drm_crtc *crtc = &pipe->crtc;
>   	struct drm_rect damage;
> -	int idx;
> +	int ret, idx;
>   
>   	if (crtc->state->mode_changed || !crtc->state->enable) {
>   		cancel_work_sync(&gdrm->work);
> @@ -557,6 +579,8 @@ void gud_pipe_update(struct drm_simple_display_pipe *pipe,
>   			gdrm->fb = NULL;
>   		}
>   		gud_clear_damage(gdrm);
> +		vfree(gdrm->shadow_buf);
> +		gdrm->shadow_buf = NULL;
>   		mutex_unlock(&gdrm->damage_lock);
>   	}
>   
> @@ -572,14 +596,19 @@ void gud_pipe_update(struct drm_simple_display_pipe *pipe,
>   	if (crtc->state->active_changed)
>   		gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, crtc->state->active);
>   
> -	if (drm_atomic_helper_damage_merged(old_state, state, &damage)) {
> -		if (gdrm->flags & GUD_DISPLAY_FLAG_FULL_UPDATE)
> -			drm_rect_init(&damage, 0, 0, fb->width, fb->height);
> -		gud_fb_queue_damage(gdrm, fb, &damage);
> -		if (!gud_async_flush)
> -			flush_work(&gdrm->work);
> -	}
> +	if (!fb)
> +		goto ctrl_disable;
>   
> +	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
> +	if (ret)
> +		goto ctrl_disable;
> +
> +	if (drm_atomic_helper_damage_merged(old_state, state, &damage))
> +		gud_fb_handle_damage(gdrm, fb, &shadow_plane_state->data[0], &damage);
> +
> +	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
> +
> +ctrl_disable:
>   	if (!crtc->state->enable)
>   		gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 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: Ivo Totev

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

  reply	other threads:[~2022-12-01  8:55 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-30 19:26 [PATCH v2 0/6] drm/gud: Use the shadow plane helper Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26 ` Noralf Trønnes
2022-11-30 19:26 ` [PATCH v2 1/6] drm/gud: Fix UBSAN warning Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-11-30 19:26 ` [PATCH v2 2/6] drm/gud: Don't retry a failed framebuffer flush Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-11-30 19:26 ` [PATCH v2 3/6] drm/gud: Split up gud_flush_work() Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-11-30 19:26 ` [PATCH v2 4/6] drm/gud: Prepare buffer for CPU access in gud_flush_work() Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-12-01  8:51   ` Thomas Zimmermann
2022-11-30 19:26 ` [PATCH v2 5/6] drm/gud: Use the shadow plane helper Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-12-01  8:55   ` Thomas Zimmermann [this message]
2022-11-30 19:26 ` [PATCH v2 6/6] drm/gud: Enable synchronous flushing by default Noralf Trønnes via B4 Submission Endpoint
2022-11-30 19:26   ` Noralf Trønnes
2022-12-01  8:57   ` Thomas Zimmermann
2022-12-01  5:55 ` [PATCH v2 0/6] drm/gud: Use the shadow plane helper Greg KH
2022-12-01 10:00   ` Noralf Trønnes
2022-12-01 10:00     ` Noralf Trønnes
2022-12-01 12:12     ` Greg KH
2022-12-01 12:12       ` Greg KH
2022-12-01 13:14       ` Noralf Trønnes
2022-12-01 13:14         ` Noralf Trønnes
2022-12-01 13:21         ` Greg KH
2022-12-01 13:21           ` Greg KH
2022-12-01 13:34           ` Javier Martinez Canillas
2022-12-01 13:34             ` Javier Martinez Canillas
2022-12-01 14:16             ` Konstantin Ryabitsev
2022-12-01 14:16               ` Konstantin Ryabitsev
2022-12-01 14:20               ` Javier Martinez Canillas
2022-12-01 14:20                 ` Javier Martinez Canillas
2022-12-01 14:27               ` Vlastimil Babka
2022-12-01 14:27                 ` Vlastimil Babka
2022-12-01 14:32                 ` Mark Brown
2022-12-01 14:32                   ` Mark Brown
2023-01-05 12:35                   ` Daniel Vetter
2023-01-05 12:35                     ` Daniel Vetter
2023-01-05 16:00                     ` Konstantin Ryabitsev
2023-01-05 16:00                       ` Konstantin Ryabitsev
2022-12-01 20:52               ` Noralf Trønnes
2022-12-01 20:52                 ` Noralf Trønnes
2022-12-06 15:57 ` Noralf Trønnes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=205fecde-723c-7c0a-e96b-6005ac43e745@suse.de \
    --to=tzimmermann@suse.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=javierm@redhat.com \
    --cc=mripard@kernel.org \
    --cc=noralf@tronnes.org \
    --cc=stable@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.