aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2009-09-14 17:48:44 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-09-17 17:36:01 -0400
commitf65d94211e2bcba17faf05a6a3809af0e4217767 (patch)
treea040777b0311b5c5a7a26f64c7d8ae9a6ac872f1 /drivers/gpu/drm/i915/i915_dma.c
parent22be172423b0007a02a06d70db8aeb4d9e64c6b3 (diff)
drm/i915: Add hangcheck timer
We set a periodic timer to check on the GPU, resetting it every time a batch is completed. If the timer elapses, we check acthd. If acthd hasn't changed in two timer periods, we assume the chip is wedged. This is implemented in such a way that it leaves the option open to employ adaptive timer intervals in the future. One could wait until several timer periods have elapsed before declaring the chip dead. If the chip comes back after several periods but before the "dead" threshold, the timer interval or dead threshold could be raised. It is important to note that while checking for active requests, we need to account for the fact that requests are removed from the list (i.e. retired) in a deferred work queue handler. This means that merely checking for an empty request_list is insufficient; the list could be non-empty yet the GPU still idle, causing the hangcheck timer to incorrectly mark the GPU as wedged (it took me a while to figure that out---sigh...) Signed-off-by: Ben Gamari <bgamari.foss@gmail.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 7a73b2941eb7..08a5048335e1 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1447,6 +1447,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1447 if (!IS_IGDNG(dev)) 1447 if (!IS_IGDNG(dev))
1448 intel_opregion_init(dev, 0); 1448 intel_opregion_init(dev, 0);
1449 1449
1450 setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
1451 (unsigned long) dev);
1450 return 0; 1452 return 0;
1451 1453
1452out_workqueue_free: 1454out_workqueue_free:
@@ -1467,6 +1469,7 @@ int i915_driver_unload(struct drm_device *dev)
1467 struct drm_i915_private *dev_priv = dev->dev_private; 1469 struct drm_i915_private *dev_priv = dev->dev_private;
1468 1470
1469 destroy_workqueue(dev_priv->wq); 1471 destroy_workqueue(dev_priv->wq);
1472 del_timer_sync(&dev_priv->hangcheck_timer);
1470 1473
1471 io_mapping_free(dev_priv->mm.gtt_mapping); 1474 io_mapping_free(dev_priv->mm.gtt_mapping);
1472 if (dev_priv->mm.gtt_mtrr >= 0) { 1475 if (dev_priv->mm.gtt_mtrr >= 0) {