Re: [PATCH v2 8/9] drm/i915: Perform vblank evasion around legacy cursor updates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2024-01-16 at 22:49 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>
> 
> Our legacy cursor updates are actually mailbox updates.
> Ie. the hardware latches things once per frame on start of
> vblank, but we issue an number of updates per frame,
> withough any attempt to synchronize against the vblank
> in software. So in theory only the last update issued
> during the frame will latch, and the previous ones are
> discarded.
> 
> However this can lead to problems with maintaining the
> ggtt/iommu mappings as we have no idea which updates
> will actually latch.
> 
> The problem is exacerbated by the hardware's annoying disarming
> behaviour; any non-arming register write will disarm an already
> armed update, only to be rearmed later by the arming register
> (CURBASE in case of cursors). If a disarming write happens
> just before the start of vblank, and the arming write happens
> after start of vblank we have effectively prevented the hardware
> from latching anything. And if we manage to straddle multiple
> sequential vblank starts in this manner we effectively prevent
> the hardware from latching any new registers for an arbitrary
> amount of time. This provides more time for the (potentially
> still in use by the hardware) gtt/iommu mappings to be torn
> down.
> 
> A partial solution, of course, is to use vblank evasion to
> avoid the register writes from spreading on both sides of
> the start of vblank.
> 
> I've previously highlighted this problem as a general issue
> affecting mailbox updates. I even added some notes to the
> {i9xx,skl}_crtc_planes_update_arm() to remind us that the noarm
> and arm phases both need to pulled into the vblank evasion
> critical section if we actually decided to implement mailbox
> updates in general. But as I never impelemented the noarm+arm
> split for cursors we don't have to worry about that for the
> moment.
> 
> We've been lucky enough so far that this hasn't really caused
> problems. One thing that does help is that Xorg generally
> sticks to the same cursor BO. But igt seems pretty good at
> hitting this on MTL now, so apparently we have to start
> thinking about this.
> 
> v2: Wait for PSR exit to avoid the vblank evasion timeout (1ms)
>     tripping due to PSR exit latency (~5ms typically)
> 
> Reviewed-by: Uma Shankar <uma.shankar@xxxxxxxxx>
> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx>

I'm sorry for those two empty emails I sent earlier. Some problem with
my mail client. After restarting the client it seems to work again:

Reviewed-by: Jouni Högander <jouni.hogander@xxxxxxxxx>

> ---
>  drivers/gpu/drm/i915/display/intel_cursor.c | 31 ++++++++++++++++---
> --
>  1 file changed, 24 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c
> b/drivers/gpu/drm/i915/display/intel_cursor.c
> index ecff90e233f0..f8b33999d43f 100644
> --- a/drivers/gpu/drm/i915/display/intel_cursor.c
> +++ b/drivers/gpu/drm/i915/display/intel_cursor.c
> @@ -22,6 +22,7 @@
>  #include "intel_frontbuffer.h"
>  #include "intel_psr.h"
>  #include "intel_psr_regs.h"
> +#include "intel_vblank.h"
>  #include "skl_watermark.h"
>  
>  #include "gem/i915_gem_object.h"
> @@ -665,12 +666,14 @@ intel_legacy_cursor_update(struct drm_plane
> *_plane,
>  {
>         struct intel_plane *plane = to_intel_plane(_plane);
>         struct intel_crtc *crtc = to_intel_crtc(_crtc);
> +       struct drm_i915_private *i915 = to_i915(plane->base.dev);
>         struct intel_plane_state *old_plane_state =
>                 to_intel_plane_state(plane->base.state);
>         struct intel_plane_state *new_plane_state;
>         struct intel_crtc_state *crtc_state =
>                 to_intel_crtc_state(crtc->base.state);
>         struct intel_crtc_state *new_crtc_state;
> +       struct intel_vblank_evade_ctx evade;
>         int ret;
>  
>         /*
> @@ -763,13 +766,25 @@ intel_legacy_cursor_update(struct drm_plane
> *_plane,
>          */
>         crtc_state->active_planes = new_crtc_state->active_planes;
>  
> -       /*
> -        * Technically we should do a vblank evasion here to make
> -        * sure all the cursor registers update on the same frame.
> -        * For now just make sure the register writes happen as
> -        * quickly as possible to minimize the race window.
> -        */
> -       local_irq_disable();
> +       intel_vblank_evade_init(crtc_state, crtc_state, &evade);
> +
> +       intel_psr_lock(crtc_state);
> +
> +       if (!drm_WARN_ON(&i915->drm, drm_crtc_vblank_get(&crtc-
> >base))) {
> +               /*
> +                * TODO: maybe check if we're still in PSR
> +                * and skip the vblank evasion entirely?
> +                */
> +               intel_psr_wait_for_idle_locked(crtc_state);
> +
> +               local_irq_disable();
> +
> +               intel_vblank_evade(&evade);
> +
> +               drm_crtc_vblank_put(&crtc->base);
> +       } else {
> +               local_irq_disable();
> +       }
>  
>         if (new_plane_state->uapi.visible) {
>                 intel_plane_update_noarm(plane, crtc_state,
> new_plane_state);
> @@ -780,6 +795,8 @@ intel_legacy_cursor_update(struct drm_plane
> *_plane,
>  
>         local_irq_enable();
>  
> +       intel_psr_unlock(crtc_state);
> +
>         intel_plane_unpin_fb(old_plane_state);
>  
>  out_free:





[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux