Message ID | 20201120102545.4047-11-tzimmermann@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/fb-helper: Various fixes and cleanups | expand |
On Fri, Nov 20, 2020 at 11:25:45AM +0100, Thomas Zimmermann wrote: > Flushing the fbdev's shadow buffer requires vmap'ing the BO memory, which > in turn requires pinning the BO. While being pinned, the BO cannot be moved > into VRAM for scanout. Consequently, a concurrent modeset operation that > involves the fbdev framebuffer would likely fail. > > Resolve this problem be acquiring the modeset lock of the planes that use > the fbdev framebuffer. On non-atomic drivers, also acquire the mode-config > lock. This serializes the flushing of the framebuffer with concurrent > modeset operations. > > v2: > * only acquire struct drm_fb_helper.lock in damage blitter (Daniel, > Christian) > > Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Acked-by: Sam Ravnborg <sam@ravnborg.org>
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d972ce75d180..6f2763467e99 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -398,16 +398,32 @@ static int drm_fb_helper_damage_blit(struct drm_fb_helper *fb_helper, struct dma_buf_map map, dst; int ret; + /* + * We have to pin the client buffer to its current location while + * flushing the shadow buffer. In the general case, concurrent + * modesetting operations could try to move the buffer and would + * fail. The modeset has to be serialized by acquiring the reservation + * object of the underlying BO here. + * + * For fbdev emulation, we only have to protect against fbdev modeset + * operations. Nothing else will involve the client buffer's BO. So it + * is sufficient to acquire struct drm_fb_helper.lock here. + */ + mutex_lock(&fb_helper->lock); + ret = drm_client_buffer_vmap(buffer, &map); if (ret) - return ret; + goto out; dst = map; drm_fb_helper_damage_blit_real(fb_helper, clip, &dst); drm_client_buffer_vunmap(buffer); - return 0; +out: + mutex_unlock(&fb_helper->lock); + + return ret; } static void drm_fb_helper_damage_work(struct work_struct *work)
Flushing the fbdev's shadow buffer requires vmap'ing the BO memory, which in turn requires pinning the BO. While being pinned, the BO cannot be moved into VRAM for scanout. Consequently, a concurrent modeset operation that involves the fbdev framebuffer would likely fail. Resolve this problem be acquiring the modeset lock of the planes that use the fbdev framebuffer. On non-atomic drivers, also acquire the mode-config lock. This serializes the flushing of the framebuffer with concurrent modeset operations. v2: * only acquire struct drm_fb_helper.lock in damage blitter (Daniel, Christian) Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> --- drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)