• Ville Syrjälä's avatar
    drm/i915: Fix mmio vs. CS flip race on ILK+ · 75f7f3ec
    Ville Syrjälä authored
    Starting from ILK, mmio flips also cause a flip done interrupt to be
    signalled. This means if we first do a set_base and follow it
    immediately with the CS flip, we might mistake the flip done interrupt
    caused by the set_base as the flip done interrupt caused by the CS
    flip.
    
    The hardware has a flip counter which increments every time a mmio or
    CS flip is issued. It basically counts the number of DSPSURF register
    writes. This means we can sample the counter before we put the CS
    flip into the ring, and then when we get a flip done interrupt we can
    check whether the CS flip has actually performed the surface address
    update, or if the interrupt was caused by a previous but yet
    unfinished mmio flip.
    
    Even with the flip counter we still have a race condition of the CS flip
    base address update happens after the mmio flip done interrupt was
    raised but not yet processed by the driver. When the interrupt is
    eventually processed, the flip counter will already indicate that the
    CS flip has been executed, but it would not actually complete until the
    next start of vblank. We can use the DSPSURFLIVE register to check
    whether the hardware is actually scanning out of the buffer we expect,
    or if we managed hit this race window.
    
    This covers all the cases where the CS flip actually changes the base
    address. If the base address remains unchanged, we might still complete
    the CS flip before it has actually completed. But since the address
    didn't change anyway, the premature flip completion can't result in
    userspace overwriting data that's still being scanned out.
    
    CTG already has the flip counter and DSPSURFLIVE registers, and
    although the flip done interrupt is still limited to CS flips alone,
    the code now also checks the flip counter on CTG as well.
    
    v2: s/dspsurf/gtt_offset/ (Chris)
    
    Testcase: igt/kms_mmio_vs_cs_flip/setcrtc_vs_cs_flip
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73027Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
    Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@gmail.com>
    [danvet: Add g4x_ prefix to flip_count_after_eq.]
    Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
    75f7f3ec
intel_drv.h 32.7 KB