diff options
author | Mario Kleiner <mario.kleiner.de@gmail.com> | 2014-07-17 02:24:45 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-07-17 09:04:03 -0400 |
commit | 5f87e090a7368adc2290ae17ffd82a070caadd20 (patch) | |
tree | 54db7617658560a8a13e5cb87ef135c4a05b35f2 | |
parent | 826484977c29b42c8cb8c42bd41acaa6e152a4bb (diff) |
drm/radeon: Make classic pageflip completion path less racy.
Need to protect mmio flip programming by event lock as well.
Need to also first enable pflip irq, then mmio program,
otherwise a flip completion may get unnoticed in the vblank
of actual completion if the flip is programmed, but
radeon_flip_work_func gets preempted immediately after
mmio programming and before vblank. In that case the
vblank irq handler wouldn't run radeon_crtc_handle_vblank()
with the completion check routine, miss the completed flip,
and only notice one vblank after actual completion, causing
a false/delayed report of flip completion.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 0a22a1bb688c..bf25061c8ac4 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -407,15 +407,15 @@ static void radeon_flip_work_func(struct work_struct *__work) radeon_fence_unref(&work->fence); } - /* do the flip (mmio) */ - radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); - /* We borrow the event spin lock for protecting flip_status */ spin_lock_irqsave(&crtc->dev->event_lock, flags); /* set the proper interrupt */ radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id); + /* do the flip (mmio) */ + radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); + radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); up_read(&rdev->exclusive_lock); |