提交 bc0c7f14 编写于 作者: D Daniel Vetter 提交者: Chris Wilson

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: NDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
上级 24d05927
...@@ -2256,9 +2256,6 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -2256,9 +2256,6 @@ int i915_driver_unload(struct drm_device *dev)
i915_mch_dev = NULL; i915_mch_dev = NULL;
spin_unlock(&mchdev_lock); spin_unlock(&mchdev_lock);
destroy_workqueue(dev_priv->wq);
del_timer_sync(&dev_priv->hangcheck_timer);
io_mapping_free(dev_priv->mm.gtt_mapping); io_mapping_free(dev_priv->mm.gtt_mapping);
if (dev_priv->mm.gtt_mtrr >= 0) { if (dev_priv->mm.gtt_mtrr >= 0) {
mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base,
...@@ -2283,6 +2280,9 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -2283,6 +2280,9 @@ int i915_driver_unload(struct drm_device *dev)
vga_client_register(dev->pdev, NULL, NULL, NULL); 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) if (dev->pdev->msi_enabled)
pci_disable_msi(dev->pdev); pci_disable_msi(dev->pdev);
...@@ -2307,6 +2307,8 @@ int i915_driver_unload(struct drm_device *dev) ...@@ -2307,6 +2307,8 @@ int i915_driver_unload(struct drm_device *dev)
intel_teardown_mchbar(dev); intel_teardown_mchbar(dev);
destroy_workqueue(dev_priv->wq);
pci_dev_put(dev_priv->bridge_dev); pci_dev_put(dev_priv->bridge_dev);
kfree(dev->dev_private); kfree(dev->dev_private);
......
...@@ -4408,7 +4408,7 @@ i915_gem_idle(struct drm_device *dev) ...@@ -4408,7 +4408,7 @@ i915_gem_idle(struct drm_device *dev)
* And not confound mm.suspended! * And not confound mm.suspended!
*/ */
dev_priv->mm.suspended = 1; dev_priv->mm.suspended = 1;
del_timer(&dev_priv->hangcheck_timer); del_timer_sync(&dev_priv->hangcheck_timer);
i915_kernel_lost_context(dev); i915_kernel_lost_context(dev);
i915_gem_cleanup_ringbuffer(dev); i915_gem_cleanup_ringbuffer(dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册