Mario Kleiner
2016-Nov-23 06:58 UTC
[Nouveau] [PATCH] drm/nouveau/kms/nv50: Fix atomic pageflip events.
The new atomic modesetting/pageflip code for nv50+ for Linux 4.10+ no longer uses pageflip irq's to signal flip completion. Instead it polls for flip completion from within a kthread/work queue. This creates a race between the vblank irq handler updating the vblank count and timestamp for the vblank of flip completion, and the kthread's polling code detecting flip completion and sending out the flip completion event. Depending on who executes a few microseconds earlier, the flip completion event will either contain correct count/timestamp or a stale count/timestamp from the previous vblank. This error was observed for about 50% of all executed flips, e.g., observable under DRI2 by the Xorg.log filling with flip handler warning messages. Call drm_accurate_vblank_count() before sending out flip completion events to enforce a vblank count/ts update for the vblank of flip completion and avoid stale counts/timestamps. This fix leads to one redundant call to drm_update_vblank_count for each completed flip, but no other side effects. On a ~6 year old Core i7 M620@ 2.67GHz the redundant call costs about 10 usecs per flip Successfully tested on GeForce 9500/9600/330M so far. Signed-off-by: Mario Kleiner <mario.kleiner.de at gmail.com> Cc: Ben Skeggs <bskeggs at redhat.com> --- drivers/gpu/drm/nouveau/nv50_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a9855a4..ad9aedb 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -4087,6 +4087,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) for_each_crtc_in_state(state, crtc, crtc_state, i) { if (crtc->state->event) { unsigned long flags; + /* Get correct count/ts if racing with vblank irq */ + drm_accurate_vblank_count(crtc); spin_lock_irqsave(&crtc->dev->event_lock, flags); drm_crtc_send_vblank_event(crtc, crtc->state->event); spin_unlock_irqrestore(&crtc->dev->event_lock, flags); -- 2.7.0
Possibly Parallel Threads
- [Intel-gfx] [PATCH 15/16] drm/nouveau: Convert nouveau to use new iterator macros
- [PATCH v2 6/7] drm/nouveau: Convert nouveau to use new iterator macros, v2.
- [PATCH 15/16] drm/nouveau: Convert nouveau to use new iterator macros
- [PATCH 1/2] drm/nouveau: Use drm_vblank_count_and_time() for pageflip completion events.
- [PATCH] drm/nouveau: Fix pre-nv50 pageflip events