From: Thomas Zimmermann Date: Mon, 27 Apr 2026 15:00:39 +0000 (+0200) Subject: drm/vmwgfx: Move vblank handling into separate helper X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c6113e07af73046ef32ac0acc9cdc15fb62c4da;p=thirdparty%2Fkernel%2Flinux.git drm/vmwgfx: Move vblank handling into separate helper Decouple vblank handling from the underlying hrtimer. This will be helpful for replacing vmwgfx's vblank timer with DRM's common implementation. The new helper vmw_vkms_handle_vblank_timeout() can later be used as callback for DRM's handle_vblank call as-is. The helper also keeps the current semantics for restarting the timer. It returns true to restart the next vblank timeout even if it could not acquire vmwgfx's vblank lock. The remaining code in vmw_vkms_vblank_simulate() will be replaced by the DRM implementation in a later patch. v2: - clarify return-value semantics in commit message (Zack) Signed-off-by: Thomas Zimmermann Reviewed-by: Zack Rusin Link: https://patch.msgid.link/20260427150250.699768-3-tzimmermann@suse.de --- diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c index 7862f6972512f..15439ddd4f22a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c @@ -157,27 +157,19 @@ crc_generate_worker(struct work_struct *work) drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32); } -static enum hrtimer_restart -vmw_vkms_vblank_simulate(struct hrtimer *timer) +bool +vmw_vkms_handle_vblank_timeout(struct drm_crtc *crtc) { - struct vmw_display_unit *du = container_of(timer, struct vmw_display_unit, vkms.timer); - struct drm_crtc *crtc = &du->crtc; + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); struct vmw_private *vmw = vmw_priv(crtc->dev); bool has_surface = false; - u64 ret_overrun; bool locked, ret; - ret_overrun = hrtimer_forward_now(&du->vkms.timer, - du->vkms.period_ns); - if (ret_overrun != 1) - drm_dbg_driver(crtc->dev, "vblank timer missed %lld frames.\n", - ret_overrun - 1); - locked = vmw_vkms_vblank_trylock(crtc); ret = drm_crtc_handle_vblank(crtc); WARN_ON(!ret); if (!locked) - return HRTIMER_RESTART; + return true; has_surface = du->vkms.surface != NULL; vmw_vkms_unlock(crtc); @@ -200,6 +192,27 @@ vmw_vkms_vblank_simulate(struct hrtimer *timer) drm_dbg_driver(crtc->dev, "Composer worker already queued\n"); } + return true; +} + +static enum hrtimer_restart +vmw_vkms_vblank_simulate(struct hrtimer *timer) +{ + struct vmw_display_unit *du = container_of(timer, struct vmw_display_unit, vkms.timer); + struct drm_crtc *crtc = &du->crtc; + u64 ret_overrun; + bool success; + + ret_overrun = hrtimer_forward_now(&du->vkms.timer, + du->vkms.period_ns); + if (ret_overrun != 1) + drm_dbg_driver(crtc->dev, "vblank timer missed %lld frames.\n", + ret_overrun - 1); + + success = vmw_vkms_handle_vblank_timeout(crtc); + if (!success) + return HRTIMER_NORESTART; + return HRTIMER_RESTART; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h index 69ddd33a8444f..0b6bbf7c44879 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h @@ -45,6 +45,7 @@ bool vmw_vkms_modeset_lock_relaxed(struct drm_crtc *crtc); bool vmw_vkms_vblank_trylock(struct drm_crtc *crtc); void vmw_vkms_unlock(struct drm_crtc *crtc); +bool vmw_vkms_handle_vblank_timeout(struct drm_crtc *crtc); bool vmw_vkms_get_vblank_timestamp(struct drm_crtc *crtc, int *max_error, ktime_t *vblank_time,