Commit 14d200c5 authored by Jesse Barnes's avatar Jesse Barnes Committed by Dave Airlie

drm/i915: capture last_vblank count at IRQ uninstall time too

In dc1336ff (set vblank enable flag correctly
across IRQ uninstall), we made sure drivers that uninstall their interrupt
handler set the vblank enabled flag correctly, so that when interrupts are
re-enabled, vblank interrupts & counts work as expected.  However I missed the
last_vblank field:  it needs to be updated as well, otherwise, at the next
drm_update_vblank_count we'll end up comparing a current count to a stale
one (the last one captured by the disable function), which may trigger the
wraparound handling, leading to a jumpy counter and hangs in drm_wait_vblank.

The jumpy counter can prevent the DRM_WAIT_ON from returning success if the
difference between the current count and the requested count is greater than
2^23, leading to timeouts or hangs, if the ioctl is restarted in a loop (as
is the case in libdrm < 2.4.4).
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Acked-by: default avatarMichel Dänzer <michel@daenzer.net>
Tested-by: default avatarTimo Aaltonen <tjaalton@cc.hut.fi>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 7d8d58b2
...@@ -276,6 +276,7 @@ int drm_irq_uninstall(struct drm_device * dev) ...@@ -276,6 +276,7 @@ int drm_irq_uninstall(struct drm_device * dev)
for (i = 0; i < dev->num_crtcs; i++) { for (i = 0; i < dev->num_crtcs; i++) {
DRM_WAKEUP(&dev->vbl_queue[i]); DRM_WAKEUP(&dev->vbl_queue[i]);
dev->vblank_enabled[i] = 0; dev->vblank_enabled[i] = 0;
dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
} }
spin_unlock_irqrestore(&dev->vbl_lock, irqflags); spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment