Re: [PATCH 1/6] drm/i915/cursor: Check joiner cursor commit status
"Borah, Chaitanya Kumar" <[email protected]> Wed, 29 Jul 2026 20:58:25 +0530
| Newsgroups | org.freedesktop.lists.intel-gfx,org.freedesktop.lists.intel-xe |
|---|---|
| Message-ID | <[email protected]> |
On 7/6/2026 5:26 PM, Nemesa Garg wrote: > In joiner mode, secondary cursor commits may still be running > even when the primary cursor commit is done. Walking the secondary > pipes also requires holding the secondary planes modeset locks. > Add intel_cursor_lock_joined_planes() to acquire modeset locks > for all secondary cursor planes. Check all joined cursor commit > status before taking the fast path. If any commit is still pending, > fallback to slow path. > > v2: Use intel_crtc_joined_pipe_mask(). [Ville] > v3: Lock secondary cursor CRTCs and planes. [sashiko] > v4: Iterate the full joined mask uniformly in both helpers, no > primary special-case. > Move the parameter-change check above the lock acquisition so > we don't grab secondary locks just to fall to slow path. [Chaitanya] > > Assisted-by: Claude:claude-sonnet-4.6 > Signed-off-by: Nemesa Garg <[email protected]> > --- > drivers/gpu/drm/i915/display/intel_cursor.c | 69 ++++++++++++++++++--- > 1 file changed, 60 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c > index 88384dea868b..af7fc1f888c4 100644 > --- a/drivers/gpu/drm/i915/display/intel_cursor.c > +++ b/drivers/gpu/drm/i915/display/intel_cursor.c > @@ -13,6 +13,7 @@ > #include <drm/drm_vblank.h> > > #include "intel_atomic.h" > +#include "intel_crtc.h" do we need this header here? I think it is only needed for intel_crtc_get_vblank_counter(). Add it with the patch that adds the dependency. > #include "intel_cursor.h" > #include "intel_cursor_regs.h" > #include "intel_de.h" > @@ -796,6 +797,50 @@ void intel_cursor_unpin_work(struct kthread_work *base) > intel_plane_destroy_state(&plane->base, &plane_state->uapi); > } > > +static int intel_cursor_lock_joined_planes(struct intel_display *display, > + const struct intel_crtc_state *crtc_state, > + struct drm_modeset_acquire_ctx *ctx) > +{ > + struct intel_crtc *pipe_crtc; > + int ret; > + > + for_each_intel_crtc_in_pipe_mask(display, pipe_crtc, > + intel_crtc_joined_pipe_mask(crtc_state)) { > + struct intel_plane *pipe_plane = > + intel_crtc_get_plane(pipe_crtc, PLANE_CURSOR); > + > + ret = drm_modeset_lock(&pipe_crtc->base.mutex, ctx); > + if (ret) > + return ret; > + > + ret = drm_modeset_lock(&pipe_plane->base.mutex, ctx); > + if (ret) > + return ret; > + } > + return 0; > +} > + > +static bool > +intel_cursor_joiner_commits_idle(struct intel_display *display, > + const struct intel_crtc_state *crtc_state) > +{ > + struct intel_crtc *pipe_crtc; > + > + for_each_intel_crtc_in_pipe_mask(display, pipe_crtc, > + intel_crtc_joined_pipe_mask(crtc_state)) { > + struct intel_plane *pipe_plane = > + intel_crtc_get_plane(pipe_crtc, PLANE_CURSOR); > + struct intel_plane_state *pipe_plane_state = > + to_intel_plane_state(pipe_plane->base.state); > + > + if (pipe_plane_state->uapi.commit && > + !try_wait_for_completion(&pipe_plane_state->uapi.commit->hw_done)) > + return false; > + } > + > + return true; > +} > + > static int > intel_legacy_cursor_update(struct drm_plane *_plane, > struct drm_crtc *_crtc, > @@ -833,15 +878,6 @@ intel_legacy_cursor_update(struct drm_plane *_plane, > crtc_state->joiner_pipes) > goto slow; > > - /* > - * Don't do an async update if there is an outstanding commit modifying > - * the plane. This prevents our async update's changes from getting > - * overridden by a previous synchronous update's state. > - */ > - if (old_plane_state->uapi.commit && > - !try_wait_for_completion(&old_plane_state->uapi.commit->hw_done)) > - goto slow; > - > /* > * If any parameters change that may affect watermarks, > * take the slowpath. Only changing fb or position should be > @@ -855,6 +891,21 @@ intel_legacy_cursor_update(struct drm_plane *_plane, > !old_plane_state->uapi.fb != !fb) > goto slow; > > + ret = intel_cursor_lock_joined_planes(display, crtc_state, ctx); > + if (ret == -EDEADLK) > + return ret; > + if (ret) > + goto slow; > + > + /* > + * Don't do an async update if there is an outstanding commit modifying > + * any of the joined cursor planes. This prevents our async update's > + * changes from getting overridden by a previous synchronous update's > + * state. > + */ > + if (!intel_cursor_joiner_commits_idle(display, crtc_state)) > + goto slow; > + > new_plane_state = to_intel_plane_state(intel_plane_duplicate_state(&plane->base)); > if (!new_plane_state) > return -ENOMEM;