public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
From: Alex Deucher <alexdeucher@gmail.com>
To: Thomas Zimmermann <tzimmermann@suse.de>
Cc: alexander.deucher@amd.com, christian.koenig@amd.com,
	airlied@gmail.com, simona@ffwll.ch,
	amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm/amdgpu: Replace VKMS vblank timer with common implementation
Date: Mon, 20 Apr 2026 10:28:42 -0400	[thread overview]
Message-ID: <CADnq5_Ms0U0Pmpt3cvz6zFLZGrG0f6-x=4Nqam2XU8+gXGZA1w@mail.gmail.com> (raw)
In-Reply-To: <20260420125223.234974-1-tzimmermann@suse.de>

Applied.  Thanks!

On Mon, Apr 20, 2026 at 8:59 AM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Replace amdgpu's custom vblank timers with the shared implementation
> in DRM's vblank code. Both are built upon hrtimers. The vblank logic
> is identical.
>
> The shared helpers contain all initialization internally. They also
> handle a number of deadlocks and race conditions that are present in
> amdgpu.
>
> Also remove the set-but-unused field vsync_timer_enabled from struct
> amdgpu_crtc.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h |   4 -
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c | 123 +----------------------
>  2 files changed, 3 insertions(+), 124 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index 51ab1a332615..8069fc41cc7f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -38,7 +38,6 @@
>  #include <drm/drm_probe_helper.h>
>  #include <linux/i2c.h>
>  #include <linux/i2c-algo-bit.h>
> -#include <linux/hrtimer.h>
>  #include "amdgpu_irq.h"
>
>  #include <drm/display/drm_dp_mst_helper.h>
> @@ -505,9 +504,6 @@ struct amdgpu_crtc {
>         u32 line_time;
>         u32 lb_vblank_lead_lines;
>         struct drm_display_mode hw_mode;
> -       /* for virtual dce */
> -       struct hrtimer vblank_timer;
> -       enum amdgpu_interrupt_state vsync_timer_enabled;
>
>         int otg_inst;
>         struct drm_pending_vblank_event *event;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> index e54295b56282..9f497e9c65b8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
> @@ -5,6 +5,7 @@
>  #include <drm/drm_simple_kms_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_vblank.h>
> +#include <drm/drm_vblank_helper.h>
>
>  #include "amdgpu.h"
>  #ifdef CONFIG_DRM_AMDGPU_SI
> @@ -42,81 +43,6 @@ static const u32 amdgpu_vkms_formats[] = {
>         DRM_FORMAT_XRGB8888,
>  };
>
> -static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
> -{
> -       struct amdgpu_crtc *amdgpu_crtc = container_of(timer, struct amdgpu_crtc, vblank_timer);
> -       struct drm_crtc *crtc = &amdgpu_crtc->base;
> -       struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> -       u64 ret_overrun;
> -       bool ret;
> -
> -       ret_overrun = hrtimer_forward_now(&amdgpu_crtc->vblank_timer,
> -                                         output->period_ns);
> -       if (ret_overrun != 1)
> -               drm_warn(amdgpu_crtc->base.dev,
> -                        "%s: vblank timer overrun count: %llu\n",
> -                        __func__, ret_overrun);
> -
> -       ret = drm_crtc_handle_vblank(crtc);
> -       /* Don't queue timer again when vblank is disabled. */
> -       if (!ret)
> -               return HRTIMER_NORESTART;
> -
> -       return HRTIMER_RESTART;
> -}
> -
> -static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
> -{
> -       struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> -       struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
> -       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> -
> -       drm_calc_timestamping_constants(crtc, &crtc->mode);
> -
> -       out->period_ns = ktime_set(0, vblank->framedur_ns);
> -       hrtimer_start(&amdgpu_crtc->vblank_timer, out->period_ns, HRTIMER_MODE_REL);
> -
> -       return 0;
> -}
> -
> -static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
> -{
> -       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> -
> -       hrtimer_try_to_cancel(&amdgpu_crtc->vblank_timer);
> -}
> -
> -static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
> -                                            int *max_error,
> -                                            ktime_t *vblank_time,
> -                                            bool in_vblank_irq)
> -{
> -       struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
> -       struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> -       struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> -
> -       if (!READ_ONCE(vblank->enabled)) {
> -               *vblank_time = ktime_get();
> -               return true;
> -       }
> -
> -       *vblank_time = READ_ONCE(amdgpu_crtc->vblank_timer.node.expires);
> -
> -       if (WARN_ON(*vblank_time == vblank->time))
> -               return true;
> -
> -       /*
> -        * To prevent races we roll the hrtimer forward before we do any
> -        * interrupt processing - this is how real hw works (the interrupt is
> -        * only generated after all the vblank registers are updated) and what
> -        * the vblank core expects. Therefore we need to always correct the
> -        * timestampe by one frame.
> -        */
> -       *vblank_time -= output->period_ns;
> -
> -       return true;
> -}
> -
>  static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
>         .set_config             = drm_atomic_helper_set_config,
>         .destroy                = drm_crtc_cleanup,
> @@ -124,45 +50,11 @@ static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
>         .reset                  = drm_atomic_helper_crtc_reset,
>         .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
>         .atomic_destroy_state   = drm_atomic_helper_crtc_destroy_state,
> -       .enable_vblank          = amdgpu_vkms_enable_vblank,
> -       .disable_vblank         = amdgpu_vkms_disable_vblank,
> -       .get_vblank_timestamp   = amdgpu_vkms_get_vblank_timestamp,
> +       DRM_CRTC_VBLANK_TIMER_FUNCS,
>  };
>
> -static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
> -                                          struct drm_atomic_state *state)
> -{
> -       drm_crtc_vblank_on(crtc);
> -}
> -
> -static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
> -                                           struct drm_atomic_state *state)
> -{
> -       drm_crtc_vblank_off(crtc);
> -}
> -
> -static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
> -                                         struct drm_atomic_state *state)
> -{
> -       unsigned long flags;
> -       if (crtc->state->event) {
> -               spin_lock_irqsave(&crtc->dev->event_lock, flags);
> -
> -               if (drm_crtc_vblank_get(crtc) != 0)
> -                       drm_crtc_send_vblank_event(crtc, crtc->state->event);
> -               else
> -                       drm_crtc_arm_vblank_event(crtc, crtc->state->event);
> -
> -               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> -
> -               crtc->state->event = NULL;
> -       }
> -}
> -
>  static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
> -       .atomic_flush   = amdgpu_vkms_crtc_atomic_flush,
> -       .atomic_enable  = amdgpu_vkms_crtc_atomic_enable,
> -       .atomic_disable = amdgpu_vkms_crtc_atomic_disable,
> +       DRM_CRTC_HELPER_VBLANK_FUNCS,
>  };
>
>  static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> @@ -187,10 +79,6 @@ static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
>         amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
>         amdgpu_crtc->encoder = NULL;
>         amdgpu_crtc->connector = NULL;
> -       amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
> -
> -       hrtimer_setup(&amdgpu_crtc->vblank_timer, &amdgpu_vkms_vblank_simulate, CLOCK_MONOTONIC,
> -                     HRTIMER_MODE_REL);
>
>         return ret;
>  }
> @@ -538,11 +426,6 @@ static int amdgpu_vkms_sw_init(struct amdgpu_ip_block *ip_block)
>  static int amdgpu_vkms_sw_fini(struct amdgpu_ip_block *ip_block)
>  {
>         struct amdgpu_device *adev = ip_block->adev;
> -       int i = 0;
> -
> -       for (i = 0; i < adev->mode_info.num_crtc; i++)
> -               if (adev->mode_info.crtcs[i])
> -                       hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
>
>         drm_kms_helper_poll_fini(adev_to_drm(adev));
>         drm_mode_config_cleanup(adev_to_drm(adev));
> --
> 2.53.0
>

  reply	other threads:[~2026-04-20 14:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20 12:51 [PATCH] drm/amdgpu: Replace VKMS vblank timer with common implementation Thomas Zimmermann
2026-04-20 14:28 ` Alex Deucher [this message]
2026-04-22 23:48 ` Claude review: " Claude Code Review Bot
2026-04-22 23:48 ` Claude Code Review Bot

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='CADnq5_Ms0U0Pmpt3cvz6zFLZGrG0f6-x=4Nqam2XU8+gXGZA1w@mail.gmail.com' \
    --to=alexdeucher@gmail.com \
    --cc=airlied@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox