lkml.org 
[lkml]   [2016]   [Mar]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 231/342] drm: Fix drm_vblank_pre/post_modeset regression from Linux 4.4
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Mario Kleiner <mario.kleiner.de@gmail.com>

    commit c61934ed9a0e3911a9935df26858726a7ec35ec0 upstream.

    Changes to drm_update_vblank_count() in Linux 4.4 broke the
    behaviour of the pre/post modeset functions as the new update
    code doesn't deal with hw vblank counter resets inbetween calls
    to drm_vblank_pre_modeset an drm_vblank_post_modeset, as it
    should.

    This causes mistreatment of such hw counter resets as counter
    wraparound, and thereby large forward jumps of the software
    vblank counter which in turn cause vblank event dispatching
    and vblank waits to fail/hang --> userspace clients hang.

    This symptom was reported on radeon-kms to cause a infinite
    hang of KDE Plasma 5 shell's login procedure, preventing users
    from logging in.

    Fix this by detecting when drm_update_vblank_count() is called
    inside a pre->post modeset interval. If so, clamp valid vblank
    increments to the safe values 0 and 1, pretty much restoring
    the update behavior of the old update code of Linux 4.3 and
    earlier. Also reset the last recorded hw vblank count at call
    to drm_vblank_post_modeset() to be safe against hw that after
    modesetting, dpms on etc. only fires its first vblank irq after
    drm_vblank_post_modeset() was already called.

    Reported-by: Vlastimil Babka <vbabka@suse.cz>
    Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
    Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Tested-by: Vlastimil Babka <vbabka@suse.cz>
    Cc: michel@daenzer.net
    Cc: vbabka@suse.cz
    Cc: ville.syrjala@linux.intel.com
    Cc: daniel.vetter@ffwll.ch
    Cc: dri-devel@lists.freedesktop.org
    Cc: alexander.deucher@amd.com
    Cc: christian.koenig@amd.com
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/gpu/drm/drm_irq.c | 16 ++++++++++++++++
    1 file changed, 16 insertions(+)

    --- a/drivers/gpu/drm/drm_irq.c
    +++ b/drivers/gpu/drm/drm_irq.c
    @@ -222,6 +222,21 @@ static void drm_update_vblank_count(stru
    }

    /*
    + * Within a drm_vblank_pre_modeset - drm_vblank_post_modeset
    + * interval? If so then vblank irqs keep running and it will likely
    + * happen that the hardware vblank counter is not trustworthy as it
    + * might reset at some point in that interval and vblank timestamps
    + * are not trustworthy either in that interval. Iow. this can result
    + * in a bogus diff >> 1 which must be avoided as it would cause
    + * random large forward jumps of the software vblank counter.
    + */
    + if (diff > 1 && (vblank->inmodeset & 0x2)) {
    + DRM_DEBUG_VBL("clamping vblank bump to 1 on crtc %u: diffr=%u"
    + " due to pre-modeset.\n", pipe, diff);
    + diff = 1;
    + }
    +
    + /*
    * FIMXE: Need to replace this hack with proper seqlocks.
    *
    * Restrict the bump of the software vblank counter to a safe maximum
    @@ -1575,6 +1590,7 @@ void drm_vblank_post_modeset(struct drm_
    if (vblank->inmodeset) {
    spin_lock_irqsave(&dev->vbl_lock, irqflags);
    dev->vblank_disable_allowed = true;
    + drm_reset_vblank_timestamp(dev, pipe);
    spin_unlock_irqrestore(&dev->vbl_lock, irqflags);

    if (vblank->inmodeset & 0x2)
    \
     
     \ /
      Last update: 2016-03-02 01:41    [W:5.255 / U:0.340 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site