Before updating the display from the console's shadow buffer, the dirty worker now waits for a vblank. This allows several screen updates to pile up and acts as a rate limiter. If a DRM master is present, it could interfere with the vblank. Don't wait in this case.
v3: * add back helper->lock * acquire DRM master status while waiting for vblank v2: * don't hold helper->lock while waiting for vblank Signed-off-by: Thomas Zimmermann <tzimmerm...@suse.de> --- drivers/gpu/drm/drm_fb_helper.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 937c3939e502..e0b780634a84 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -364,9 +364,29 @@ static void drm_fb_helper_fb_dirty(struct drm_fb_helper *helper) struct drm_device *dev = helper->dev; struct drm_clip_rect *clip = &helper->damage_clip; struct drm_clip_rect clip_copy; + struct drm_crtc *crtc; unsigned long flags; int ret; + /* + * Rate-limit update frequency to vblank. If there's a DRM master + * present, it could interfere while we're waiting for the vblank + * event. Don't wait in this case. + */ + mutex_lock(&helper->lock); + if (!drm_master_internal_acquire(helper->dev)) { + goto unlock; + } + crtc = helper->client.modesets[0].crtc; + ret = drm_crtc_vblank_get(crtc); + if (!ret) { + drm_crtc_wait_one_vblank(crtc); + drm_crtc_vblank_put(crtc); + } + drm_master_internal_release(helper->dev); +unlock: + mutex_unlock(&helper->lock); + if (drm_WARN_ON_ONCE(dev, !helper->funcs->fb_dirty)) return; -- 2.49.0