> -----Original Message-----
> From: Intel-gfx <[email protected]> On Behalf Of Maarten
> Lankhorst
> Sent: Wednesday, January 21, 2026 7:23 PM
> To: [email protected]; [email protected]
> Cc: Mike Galbraith <[email protected]>; Mario Kleiner
> <[email protected]>; Thomas Gleixner <[email protected]>; Sebastian
> Andrzej Siewior <[email protected]>; Maarten Lankhorst
> <[email protected]>
> Subject: [i915-rt v5 10/21] drm/i915: Use preempt_disable/enable_rt() where
> recommended
> 
> From: Mike Galbraith <[email protected]>
> 
> Mario Kleiner suggest in commit
>   ad3543ede630f ("drm/intel: Push get_scanout_position() timestamping into kms
> driver.")
> 
> a spots where preemption should be disabled on PREEMPT_RT. The difference is
> that on PREEMPT_RT the intel_uncore::lock disables neither preemption nor
> interrupts and so region remains preemptible.
> 
> The area covers only register reads and writes. The part that worries me
> is:
> - __intel_get_crtc_scanline() the worst case is 100us if no match is
>   found.
> 
> - intel_crtc_scanlines_since_frame_timestamp() not sure how long this
>   may take in the worst case.
> 
> It was in the RT queue for a while and nobody complained.
> Disable preemption on PREEPMPT_RT during timestamping.

Looks Good to me.
Reviewed-by: Uma Shankar <[email protected]>

> [bigeasy: patch description.]
> 
> Cc: Mario Kleiner <[email protected]>
> Signed-off-by: Mike Galbraith <[email protected]>
> Signed-off-by: Thomas Gleixner <[email protected]>
> Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> Signed-off-by: Maarten Lankhorst <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_vblank.c | 43 ++++++++++++++++-----
>  1 file changed, 33 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c
> b/drivers/gpu/drm/i915/display/intel_vblank.c
> index 6bc784563a7c1..e204c260b9aef 100644
> --- a/drivers/gpu/drm/i915/display/intel_vblank.c
> +++ b/drivers/gpu/drm/i915/display/intel_vblank.c
> @@ -316,6 +316,20 @@ static void intel_vblank_section_exit(struct 
> intel_display
> *display)
>       struct intel_uncore *uncore = to_intel_uncore(display->drm);
>       spin_unlock(&uncore->lock);
>  }
> +
> +static void intel_vblank_section_enter_irqf(struct intel_display *display, 
> unsigned
> long *flags)
> +     __acquires(i915->uncore.lock)
> +{
> +     struct intel_uncore *uncore = to_intel_uncore(display->drm);
> +     spin_lock_irqsave(&uncore->lock, *flags); }
> +
> +static void intel_vblank_section_exit_irqf(struct intel_display *display, 
> unsigned
> long flags)
> +     __releases(i915->uncore.lock)
> +{
> +     struct intel_uncore *uncore = to_intel_uncore(display->drm);
> +     spin_unlock_irqrestore(&uncore->lock, flags); }
>  #else
>  static void intel_vblank_section_enter(struct intel_display *display)  { @@ 
> -324,6
> +338,17 @@ static void intel_vblank_section_enter(struct intel_display 
> *display)
> static void intel_vblank_section_exit(struct intel_display *display)  {  }
> +
> +static void intel_vblank_section_enter_irqf(struct intel_display
> +*display, unsigned long *flags) {
> +     *flags = 0;
> +}
> +
> +static void intel_vblank_section_exit_irqf(struct intel_display
> +*display, unsigned long flags) {
> +     if (flags)
> +             return;
> +}
>  #endif
> 
>  static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc, @@ -360,10
> +385,10 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
>        * timing critical raw register reads, potentially with
>        * preemption disabled, so the following code must not block.
>        */
> -     local_irq_save(irqflags);
> -     intel_vblank_section_enter(display);
> +     intel_vblank_section_enter_irqf(display, &irqflags);
> 
> -     /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */
> +     if (IS_ENABLED(CONFIG_PREEMPT_RT))
> +             preempt_disable();
> 
>       /* Get optional system timestamp before query. */
>       if (stime)
> @@ -427,10 +452,10 @@ static bool i915_get_crtc_scanoutpos(struct drm_crtc
> *_crtc,
>       if (etime)
>               *etime = ktime_get();
> 
> -     /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */
> +     if (IS_ENABLED(CONFIG_PREEMPT_RT))
> +             preempt_enable();
> 
> -     intel_vblank_section_exit(display);
> -     local_irq_restore(irqflags);
> +     intel_vblank_section_exit_irqf(display, irqflags);
> 
>       /*
>        * While in vblank, position will be negative @@ -468,13 +493,11 @@ int
> intel_get_crtc_scanline(struct intel_crtc *crtc)
>       unsigned long irqflags;
>       int position;
> 
> -     local_irq_save(irqflags);
> -     intel_vblank_section_enter(display);
> +     intel_vblank_section_enter_irqf(display, &irqflags);
> 
>       position = __intel_get_crtc_scanline(crtc);
> 
> -     intel_vblank_section_exit(display);
> -     local_irq_restore(irqflags);
> +     intel_vblank_section_exit_irqf(display, irqflags);
> 
>       return position;
>  }
> --
> 2.51.0

Reply via email to