On Tuesday, January 6, 2009 10:21 am Jesse Barnes wrote:
> 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.
>
> This patch fixes fdo bug #18879, so hopefully we can apply it or another
> fix for this problem soon.

Here's an updated version I've been testing with.  It removes the change to 
drm_wait_vblank (we can still do it but it should be a separate patch).  
Suspend/resume works for me with this one too, so if it looks good on 
inspection I'd like to see it included.  Even if it doesn't fix all the VT 
switch/IRQ install bugs we have I think it's a step in the right direction 
(IRQ uninstall really does imply vblank_enable == 0).

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 1e787f8..4cc8d3d 100644
--- 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)
        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;
 

------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to