lkml.org 
[lkml]   [2009]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch 38/43] drm/i915: set vblank enabled flag correctly across IRQ install/uninstall
2.6.28-stable review patch.  If anyone has any objections, please let us know.

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

From: Jesse Barnes <jbarnes@virtuousgeek.org>

commit dc1336ff4fe08ae7cfe8301bfd7f0b2cfd31d20a upstream.

In the absence of kernel mode setting, many drivers disable IRQs across VT
switch. The core DRM vblank code is missing a check for this case however;
even after IRQ disable, the vblank code will still have the vblank_enabled
flag set, so unless we track the fact that they're disabled at IRQ uninstall
time, when we VT switch back in we won't actually re-enable them, which means
any apps waiting on vblank before the switch will hang.

This patch does that and also adds a sanity check to the wait condition to
look for the irq_enabled flag in general, as well as adding a wakeup to the
IRQ uninstall path.

Fixes fdo bug #18879 with compiz hangs at VT switch.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
drivers/gpu/drm/drm_irq.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -259,7 +259,8 @@ EXPORT_SYMBOL(drm_irq_install);
*/
int drm_irq_uninstall(struct drm_device * dev)
{
- int irq_enabled;
+ unsigned long irqflags;
+ int irq_enabled, i;

if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
@@ -269,6 +270,16 @@ int drm_irq_uninstall(struct drm_device
dev->irq_enabled = 0;
mutex_unlock(&dev->struct_mutex);

+ /*
+ * Wake up any waiters so they don't hang.
+ */
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ for (i = 0; i < dev->num_crtcs; i++) {
+ DRM_WAKEUP(&dev->vbl_queue[i]);
+ dev->vblank_enabled[i] = 0;
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+
if (!irq_enabled)
return -EINVAL;

@@ -617,8 +628,9 @@ int drm_wait_vblank(struct drm_device *d
DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
vblwait->request.sequence, crtc);
DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
- ((drm_vblank_count(dev, crtc)
- - vblwait->request.sequence) <= (1 << 23)));
+ (((drm_vblank_count(dev, crtc) -
+ vblwait->request.sequence) <= (1 << 23)) ||
+ !dev->irq_enabled));

if (ret != -EINTR) {
struct timeval now;



\
 
 \ /
  Last update: 2009-03-21 00:45    [W:0.111 / U:0.468 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site