Skip to content

Commit

Permalink
drm/i915: unload: fix error_work races
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Vetter authored and Chris Wilson committed Sep 8, 2010
1 parent 24d0592 commit bc0c7f1
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 4 deletions.
8 changes: 5 additions & 3 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -2256,9 +2256,6 @@ int i915_driver_unload(struct drm_device *dev)
i915_mch_dev = NULL;
spin_unlock(&mchdev_lock);

destroy_workqueue(dev_priv->wq);
del_timer_sync(&dev_priv->hangcheck_timer);

io_mapping_free(dev_priv->mm.gtt_mapping);
if (dev_priv->mm.gtt_mtrr >= 0) {
mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
Expand All @@ -2283,6 +2280,9 @@ int i915_driver_unload(struct drm_device *dev)
vga_client_register(dev->pdev, NULL, NULL, NULL);
}

del_timer_sync(&dev_priv->hangcheck_timer);
cancel_work_sync(&dev_priv->error_work);

if (dev->pdev->msi_enabled)
pci_disable_msi(dev->pdev);

Expand All @@ -2307,6 +2307,8 @@ int i915_driver_unload(struct drm_device *dev)

intel_teardown_mchbar(dev);

destroy_workqueue(dev_priv->wq);

pci_dev_put(dev_priv->bridge_dev);
kfree(dev->dev_private);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -4408,7 +4408,7 @@ i915_gem_idle(struct drm_device *dev)
* And not confound mm.suspended!
*/
dev_priv->mm.suspended = 1;
del_timer(&dev_priv->hangcheck_timer);
del_timer_sync(&dev_priv->hangcheck_timer);

i915_kernel_lost_context(dev);
i915_gem_cleanup_ringbuffer(dev);
Expand Down

0 comments on commit bc0c7f1

Please sign in to comment.