Thank you for your contribution! Sashiko AI review found 2 potential issue(s) 
to consider:
- [High] Calling `intel_get_crtc_scanline()` inside the tracepoint's 
`TP_fast_assign` block acquires a sleeping lock while in atomic context, 
causing a kernel panic on PREEMPT_RT.
- [Medium] The `intel_dsb_done` tracepoint is conditionally called only when a 
userspace vblank event is present, leading to unbalanced commit/done trace 
events for background updates.
--

commit b6804a525207ea31e82f537e553534efcdaa5b8f
Author: Ville Syrjälä <[email protected]>

drm/i915/dsb: Add tracepoints for DSB commit
    
This commit adds new tracepoints intel_dsb_commit and intel_dsb_done to track
when the display state buffer performs operations on the hardware.

> diff --git a/drivers/gpu/drm/i915/display/intel_display_trace.h 
> b/drivers/gpu/drm/i915/display/intel_display_trace.h
> index 504d105935bc0..06cf662931fe3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_trace.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_trace.h
[ ... ]
> @@ -681,6 +682,56 @@ TRACE_EVENT(intel_fbc_nuke,
>                     __entry->frame, __entry->scanline)
>  );
>  
> +TRACE_EVENT(intel_dsb_commit,
> +         TP_PROTO(struct intel_crtc *crtc, enum intel_dsb_id dsb_id),
> +         TP_ARGS(crtc, dsb_id),
> +
> +         TP_STRUCT__entry(
> +                          __string(dev, __dev_name_kms(crtc))
> +                          __field(char, pipe_name)
> +                          __field(u32, dsb_id)
> +                          __field(u32, frame)
> +                          __field(u32, scanline)
> +                          ),
> +
> +         TP_fast_assign(
> +                        __assign_str(dev);
> +                        __entry->pipe_name = pipe_name(crtc->pipe);
> +                        __entry->dsb_id = dsb_id;
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->scanline = intel_get_crtc_scanline(crtc);

[Severity: High]
Does calling intel_get_crtc_scanline() from within a TP_fast_assign block
cause issues on preempt-rt kernels?

When this tracepoint is active, TP_fast_assign executes in an atomic
context (RCU read-side critical section with preemption disabled).
intel_get_crtc_scanline() eventually acquires uncore->lock:

intel_get_crtc_scanline()
  intel_vblank_section_enter()
    uncore->lock (spinlock_t)

On preempt-rt, spinlock_t becomes a sleepable rt_mutex, which will cause a
scheduling while atomic panic.

> +                        ),
> +
> +         TP_printk("dev %s, pipe %c, DSB %d, frame=%u, scanline=%u",
> +                   __get_str(dev), __entry->pipe_name, __entry->dsb_id,
> +                   __entry->frame, __entry->scanline)
> +);
> +
> +TRACE_EVENT(intel_dsb_done,
> +         TP_PROTO(struct intel_crtc *crtc, enum intel_dsb_id dsb_id),
> +         TP_ARGS(crtc, dsb_id),
> +
> +         TP_STRUCT__entry(
> +                          __string(dev, __dev_name_kms(crtc))
> +                          __field(char, pipe_name)
> +                          __field(u32, dsb_id)
> +                          __field(u32, frame)
> +                          __field(u32, scanline)
> +                          ),
> +
> +         TP_fast_assign(
> +                        __assign_str(dev);
> +                        __entry->pipe_name = pipe_name(crtc->pipe);
> +                        __entry->dsb_id = dsb_id;
> +                        __entry->frame = intel_crtc_get_vblank_counter(crtc);
> +                        __entry->scanline = intel_get_crtc_scanline(crtc);

[Severity: High]
This appears to have the same preempt-rt issue as the intel_dsb_commit
tracepoint where it acquires a sleeping lock while in atomic context.

> +                        ),
> +
> +         TP_printk("dev %s, pipe %c, DSB %d, frame=%u, scanline=%u",
> +                   __get_str(dev), __entry->pipe_name, __entry->dsb_id,
> +                   __entry->frame, __entry->scanline)
> +);
> +
[ ... ]
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c 
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index 8e01e1eed291e..299d778520a22 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
[ ... ]
> @@ -1124,6 +1127,8 @@ void intel_dsb_irq_handler(struct intel_display 
> *display,
>               spin_lock(&display->drm->event_lock);
>  
>               if (crtc->dsb_event) {
> +                     trace_intel_dsb_done(crtc, dsb_id);
> +

[Severity: Medium]
Will this lead to unbalanced commit/done trace events for background updates?

The trace_intel_dsb_done() tracepoint is conditionally called only when a
userspace vblank event is present. If a commit completes in hardware
without an associated vblank event, the irq handler will skip emitting the
completion tracepoint.

>                       /*
>                        * Update vblank counter/timestamp in case it
>                        * hasn't been done yet for this frame.

-- 
Sashiko AI review · 
https://sashiko.dev/#/patchset/[email protected]?part=12

Reply via email to