drm/i915: unload: fix hotplug_work races
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 20 Aug 2010 16:26:46 +0000 (18:26 +0200)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 8 Sep 2010 09:13:24 +0000 (10:13 +0100)
hotplug_work is queued by the hotplug interrupt and only either emits
a hotplug uevent or queues a crt poll slow-work. No other locking.  So
it's safe to cancel this work _after_ irq's have been turned off.  But
before the modesetting objects are destroyed because the hotplug
function accesses them (without locking).

The current code (for kms) only switches irqs off after modesetting
teardown, hence move the irq teardown into the modeset cleanup right
before the crtc cleanup.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/intel_display.c

index 736cca8a03d487652e2a1fd408478973a348f9fa..45236e7166692c9d24071973a9f81353121242a5 100644 (file)
@@ -2275,7 +2275,7 @@ int i915_driver_unload(struct drm_device *dev)
                        dev_priv->child_dev = NULL;
                        dev_priv->child_dev_num = 0;
                }
-               drm_irq_uninstall(dev);
+
                vga_switcheroo_unregister_client(dev->pdev);
                vga_client_register(dev->pdev, NULL, NULL, NULL);
        }
index 7c9103030036d5ca12d0f534d940ef219e02fe94..20be935830b0bc6a5fcd108e744db48a68f35675 100644 (file)
@@ -6073,6 +6073,11 @@ void intel_modeset_cleanup(struct drm_device *dev)
 
        mutex_unlock(&dev->struct_mutex);
 
+       /* Disable the irq before mode object teardown, for the irq might
+        * enqueue unpin/hotplug work. */
+       drm_irq_uninstall(dev);
+       cancel_work_sync(&dev_priv->hotplug_work);
+
        drm_mode_config_cleanup(dev);
 }