summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorJesse Barnes2009-02-06 22:04:49 +0100
committerDave Airlie2009-02-08 12:40:51 +0100
commit14d200c5e5bd19219d930bbb9a5a22758c8f5bec (patch)
tree4e6109bc96a222d490c005d481a67fa4b2a8a2e7 /drivers/gpu/drm/drm_irq.c
parentdrm/i915: Unlock mutex on i915_gem_fault() error path (diff)
downloadkernel-qcow2-linux-14d200c5e5bd19219d930bbb9a5a22758c8f5bec.tar.gz
kernel-qcow2-linux-14d200c5e5bd19219d930bbb9a5a22758c8f5bec.tar.xz
kernel-qcow2-linux-14d200c5e5bd19219d930bbb9a5a22758c8f5bec.zip
drm/i915: capture last_vblank count at IRQ uninstall time too
In dc1336ff4fe08ae7cfe8301bfd7f0b2cfd31d20a (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: Jesse Barnes <jbarnes@virtuousgeek.org> Acked-by: Michel Dänzer <michel@daenzer.net> Tested-by: Timo Aaltonen <tjaalton@cc.hut.fi> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 69aa0ab28403..3795dbc0f50c 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -276,6 +276,7 @@ int drm_irq_uninstall(struct drm_device * dev)
for (i = 0; i < dev->num_crtcs; i++) {
DRM_WAKEUP(&dev->vbl_queue[i]);
dev->vblank_enabled[i] = 0;
+ dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);