aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2010-08-20 12:18:48 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-08 05:13:24 -0400
commitbc0c7f14432f7f94b16f972f2d23b8c1248249b4 (patch)
treeccbadf9db22bb0ff1db7bdb9a4414246f184a7bb /drivers/gpu/drm/i915/i915_dma.c
parent24d05927c37adf62fe8833eceba50585cb78f906 (diff)
drm/i915: unload: fix error_work races
This is the first patch to clean up module unload races due to outstanding timers/work. Preparatory step: Thou shalt not destroy the workqueue when new work might still get enqued. Now error_work gets queued by the hangcheck timer and only (atomically) reads the chip wedged status. So cancel it right after the hangcheck timer is killed. But the hangcheck is armed by interrupts, so move everything after irqs are disabled. Also change a del_timer to a del_timer_sync in the ums gem code, the hangcheck timer is self-rearming. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 9d67b4853030..736cca8a03d4 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -2256,9 +2256,6 @@ int i915_driver_unload(struct drm_device *dev)
2256 i915_mch_dev = NULL; 2256 i915_mch_dev = NULL;
2257 spin_unlock(&mchdev_lock); 2257 spin_unlock(&mchdev_lock);
2258 2258
2259 destroy_workqueue(dev_priv->wq);
2260 del_timer_sync(&dev_priv->hangcheck_timer);
2261
2262 io_mapping_free(dev_priv->mm.gtt_mapping); 2259 io_mapping_free(dev_priv->mm.gtt_mapping);
2263 if (dev_priv->mm.gtt_mtrr >= 0) { 2260 if (dev_priv->mm.gtt_mtrr >= 0) {
2264 mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, 2261 mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
@@ -2283,6 +2280,9 @@ int i915_driver_unload(struct drm_device *dev)
2283 vga_client_register(dev->pdev, NULL, NULL, NULL); 2280 vga_client_register(dev->pdev, NULL, NULL, NULL);
2284 } 2281 }
2285 2282
2283 del_timer_sync(&dev_priv->hangcheck_timer);
2284 cancel_work_sync(&dev_priv->error_work);
2285
2286 if (dev->pdev->msi_enabled) 2286 if (dev->pdev->msi_enabled)
2287 pci_disable_msi(dev->pdev); 2287 pci_disable_msi(dev->pdev);
2288 2288
@@ -2307,6 +2307,8 @@ int i915_driver_unload(struct drm_device *dev)
2307 2307
2308 intel_teardown_mchbar(dev); 2308 intel_teardown_mchbar(dev);
2309 2309
2310 destroy_workqueue(dev_priv->wq);
2311
2310 pci_dev_put(dev_priv->bridge_dev); 2312 pci_dev_put(dev_priv->bridge_dev);
2311 kfree(dev->dev_private); 2313 kfree(dev->dev_private);
2312 2314