On Thu, 28 Aug 2025, Maarten Lankhorst <d...@lankhorst.se> wrote:
> The display tracepoints will work, but drm_crtc_accurate_vblank_count()
> takes an irq lock. Use the less accurate drm_crtc_vblank_count() on
> affected platforms, which is simply an atomic_read64();
>
> Signed-off-by: Maarten Lankhorst <d...@lankhorst.se>
> ---
>  drivers/gpu/drm/i915/display/intel_crtc.c     |  9 ++--
>  drivers/gpu/drm/i915/display/intel_crtc.h     |  2 +-
>  .../drm/i915/display/intel_display_trace.h    | 48 ++++++++++---------
>  3 files changed, 31 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
> b/drivers/gpu/drm/i915/display/intel_crtc.c
> index a187db6df2d36..5c8ce35d21ca3 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.c
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -77,7 +77,7 @@ void intel_wait_for_vblank_if_active(struct intel_display 
> *display,
>               intel_crtc_wait_for_next_vblank(crtc);
>  }
>  
> -u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
> +u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc, bool 
> update_vblank)
>  {
>       struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);
>  
> @@ -85,7 +85,8 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
>               return 0;
>  
>       if (!vblank->max_vblank_count)
> -             return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
> +             return (u32)(update_vblank ? 
> drm_crtc_accurate_vblank_count(&crtc->base) :
> +                          drm_crtc_vblank_count(&crtc->base));
>  
>       return crtc->base.funcs->get_vblank_counter(&crtc->base);
>  }
> @@ -574,7 +575,7 @@ void intel_pipe_update_start(struct intel_atomic_state 
> *state,
>  
>       crtc->debug.scanline_start = scanline;
>       crtc->debug.start_vbl_time = ktime_get();
> -     crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
> +     crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc, true);
>  
>       trace_intel_pipe_update_vblank_evaded(crtc);
>       return;
> @@ -660,7 +661,7 @@ void intel_pipe_update_end(struct intel_atomic_state 
> *state,
>               intel_atomic_get_new_crtc_state(state, crtc);
>       enum pipe pipe = crtc->pipe;
>       int scanline_end = intel_get_crtc_scanline(crtc);
> -     u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
> +     u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc, true);
>       ktime_t end_vbl_time = ktime_get();
>       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.h 
> b/drivers/gpu/drm/i915/display/intel_crtc.h
> index 8c14ff8b391ea..9826d800f3bb9 100644
> --- a/drivers/gpu/drm/i915/display/intel_crtc.h
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.h
> @@ -43,7 +43,7 @@ int intel_crtc_get_pipe_from_crtc_id_ioctl(struct 
> drm_device *dev, void *data,
>  struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
>  void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
>                           struct intel_crtc *crtc);
> -u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
> +u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc, bool 
> update_vblank);
>  void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);
>  void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);
>  void intel_pipe_update_start(struct intel_atomic_state *state,
> diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h 
> b/drivers/gpu/drm/i915/display/intel_display_trace.h
> index 27ebc32cb61a5..4e9bea671effe 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_trace.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
> @@ -10,6 +10,8 @@
>  #define TRACE_SYSTEM xe
>  #endif
>  
> +#define UPDATE_VBLANK (!IS_ENABLED(CONFIG_PREEMPT_RT))

So I'm thinking leave intel_crtc_get_vblank_counter() alone completely,
and hide all the ugly parts inside the trace file:

#if IS_ENABLED(CONFIG_PREEMPT_RT)
/* Avoid irq lock in tracepoints with PREEMPT_RT=y */
static inline u32 __trace_intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
{
        struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(&crtc->base);

        if (!crtc->active)
                return 0;

        if (!vblank->max_vblank_count)
                return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
                return (u32)drm_crtc_vblank_count(&crtc->base);

        return crtc->base.funcs->get_vblank_counter(&crtc->base);
}
#else
#define __trace_intel_crtc_get_vblank_counter intel_crtc_get_vblank_counter
#endif

And then
s/intel_crtc_get_vblank_counter/__trace_intel_crtc_get_vblank_counter/
below.

BR,
Jani.

> +
>  #if !defined(__INTEL_DISPLAY_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
>  #define __INTEL_DISPLAY_TRACE_H__
>  
> @@ -85,7 +87,7 @@ TRACE_EVENT(intel_pipe_enable,
>                          memset(__entry->scanline, 0,
>                                 sizeof(__entry->scanline[0]) * 
> I915_MAX_PIPES);
>                          for_each_intel_crtc(display->drm, it__) {
> -                                __entry->frame[it__->pipe] = 
> intel_crtc_get_vblank_counter(it__);
> +                                __entry->frame[it__->pipe] = 
> intel_crtc_get_vblank_counter(it__, UPDATE_VBLANK);
>                                  __entry->scanline[it__->pipe] = 
> intel_get_crtc_scanline(it__);
>                          }
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> @@ -115,7 +117,7 @@ TRACE_EVENT(intel_pipe_disable,
>                          memset(__entry->scanline, 0,
>                                 sizeof(__entry->scanline[0]) * 
> I915_MAX_PIPES);
>                          for_each_intel_crtc(display->drm, it__) {
> -                                __entry->frame[it__->pipe] = 
> intel_crtc_get_vblank_counter(it__);
> +                                __entry->frame[it__->pipe] = 
> intel_crtc_get_vblank_counter(it__, UPDATE_VBLANK);
>                                  __entry->scanline[it__->pipe] = 
> intel_get_crtc_scanline(it__);
>                          }
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> @@ -139,7 +141,7 @@ TRACE_EVENT(intel_crtc_flip_done,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -163,7 +165,7 @@ TRACE_EVENT(intel_pipe_crc,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          memcpy(__entry->crcs, crcs, sizeof(__entry->crcs));
>                          ),
> @@ -191,7 +193,7 @@ TRACE_EVENT(intel_cpu_fifo_underrun,
>                          struct intel_crtc *crtc = 
> intel_crtc_for_pipe(display, pipe);
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -216,7 +218,7 @@ TRACE_EVENT(intel_pch_fifo_underrun,
>                          struct intel_crtc *crtc = 
> intel_crtc_for_pipe(display, pipe);
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -245,7 +247,7 @@ TRACE_EVENT(intel_memory_cxsr,
>                          memset(__entry->scanline, 0,
>                                 sizeof(__entry->scanline[0]) * 
> I915_MAX_PIPES);
>                          for_each_intel_crtc(display->drm, crtc) {
> -                                __entry->frame[crtc->pipe] = 
> intel_crtc_get_vblank_counter(crtc);
> +                                __entry->frame[crtc->pipe] = 
> intel_crtc_get_vblank_counter(crtc, UPDATE_VBLANK);
>                                  __entry->scanline[crtc->pipe] = 
> intel_get_crtc_scanline(crtc);
>                          }
>                          __entry->old = old;
> @@ -283,7 +285,7 @@ TRACE_EVENT(g4x_wm,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->primary = 
> wm->pipe[crtc->pipe].plane[PLANE_PRIMARY];
>                          __entry->sprite = 
> wm->pipe[crtc->pipe].plane[PLANE_SPRITE0];
> @@ -330,7 +332,7 @@ TRACE_EVENT(vlv_wm,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->level = wm->level;
>                          __entry->cxsr = wm->cxsr;
> @@ -367,7 +369,7 @@ TRACE_EVENT(vlv_fifo_size,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->sprite0_start = sprite0_start;
>                          __entry->sprite1_start = sprite1_start;
> @@ -397,7 +399,7 @@ TRACE_EVENT(intel_plane_async_flip,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->async_flip = async_flip;
>                          ),
> @@ -426,7 +428,7 @@ TRACE_EVENT(intel_plane_update_noarm,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->format = plane_state->hw.fb->format->format;
>                          memcpy(__entry->src, &plane_state->uapi.src, 
> sizeof(__entry->src));
> @@ -459,7 +461,7 @@ TRACE_EVENT(intel_plane_update_arm,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->format = plane_state->hw.fb->format->format;
>                          memcpy(__entry->src, &plane_state->uapi.src, 
> sizeof(__entry->src));
> @@ -489,7 +491,7 @@ TRACE_EVENT(intel_plane_disable_arm,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -523,7 +525,7 @@ TRACE_EVENT(intel_plane_scaler_update_arm,
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
>                          __entry->scaler_id = scaler_id;
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->x = x;
>                          __entry->y = y;
> @@ -558,7 +560,7 @@ TRACE_EVENT(intel_pipe_scaler_update_arm,
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
>                          __entry->scaler_id = scaler_id;
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->x = x;
>                          __entry->y = y;
> @@ -588,7 +590,7 @@ TRACE_EVENT(intel_scaler_disable_arm,
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
>                          __entry->scaler_id = scaler_id;
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -616,7 +618,7 @@ TRACE_EVENT(intel_fbc_activate,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -644,7 +646,7 @@ TRACE_EVENT(intel_fbc_deactivate,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -672,7 +674,7 @@ TRACE_EVENT(intel_fbc_nuke,
>                          __assign_str(dev);
>                          __assign_str(name);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -695,7 +697,7 @@ TRACE_EVENT(intel_crtc_vblank_work_start,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -718,7 +720,7 @@ TRACE_EVENT(intel_crtc_vblank_work_end,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          ),
>  
> @@ -743,7 +745,7 @@ TRACE_EVENT(intel_pipe_update_start,
>           TP_fast_assign(
>                          __assign_str(dev);
>                          __entry->pipe_name = pipe_name(crtc->pipe);
> -                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc, 
> UPDATE_VBLANK);
>                          __entry->scanline = intel_get_crtc_scanline(crtc);
>                          __entry->min = crtc->debug.min_vbl;
>                          __entry->max = crtc->debug.max_vbl;

-- 
Jani Nikula, Intel

Reply via email to