summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMika Kuoppala <mika.kuoppala@intel.com>2016-01-28 11:51:53 +0200
committerMika Kuoppala <mika.kuoppala@intel.com>2016-02-16 14:16:38 +0200
commit5720e01c2765cd038c9a1749ad580f866d624077 (patch)
tree0e9277408a77f124dcbc5f8c6ab3e59ad8974843
parentfb9e6d18dce895cc6a6c00d08184d8d88f746711 (diff)
drm/i915: Don't mark idle if hangcheck is duemissed_irqs
Postpone marking device idle until hangcheck has been done. This guarantees that we hold the pm ref for hangcheck. Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index ca8ea6e42eb6..7701167ad98b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2963,6 +2963,13 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring)
WARN_ON(i915_verify_lists(ring->dev));
}
+static void i915_queue_idle_work(struct drm_i915_private *dev_priv)
+{
+ mod_delayed_work(dev_priv->wq,
+ &dev_priv->mm.idle_work,
+ msecs_to_jiffies(100));
+}
+
bool
i915_gem_retire_requests(struct drm_device *dev)
{
@@ -2984,9 +2991,7 @@ i915_gem_retire_requests(struct drm_device *dev)
}
if (idle)
- mod_delayed_work(dev_priv->wq,
- &dev_priv->mm.idle_work,
- msecs_to_jiffies(100));
+ i915_queue_idle_work(dev_priv);
return idle;
}
@@ -3010,6 +3015,14 @@ i915_gem_retire_work_handler(struct work_struct *work)
round_jiffies_up_relative(HZ));
}
+static bool i915_hangcheck_active(struct drm_i915_private *dev_priv)
+{
+ if (!i915.enable_hangcheck)
+ return false;
+
+ return delayed_work_pending(&dev_priv->gpu_error.hangcheck_work);
+}
+
static void
i915_gem_idle_work_handler(struct work_struct *work)
{
@@ -3017,27 +3030,27 @@ i915_gem_idle_work_handler(struct work_struct *work)
container_of(work, typeof(*dev_priv), mm.idle_work.work);
struct drm_device *dev = dev_priv->dev;
struct intel_engine_cs *ring;
+ bool idle;
int i;
- for_each_ring(ring, dev_priv, i)
- if (!list_empty(&ring->request_list))
- return;
-
- /* we probably should sync with hangcheck here, using cancel_work_sync.
- * Also locking seems to be fubar here, ring->request_list is protected
- * by dev->struct_mutex. */
-
- intel_mark_idle(dev);
+ if (i915_hangcheck_active(dev_priv) ||
+ !mutex_trylock(&dev->struct_mutex)) {
+ i915_queue_idle_work(dev_priv);
+ return;
+ }
- if (mutex_trylock(&dev->struct_mutex)) {
- struct intel_engine_cs *ring;
- int i;
+ idle = true;
+ for_each_ring(ring, dev_priv, i)
+ idle &= list_empty(&ring->request_list);
+ if (idle) {
for_each_ring(ring, dev_priv, i)
i915_gem_batch_pool_fini(&ring->batch_pool);
- mutex_unlock(&dev->struct_mutex);
+ intel_mark_idle(dev);
}
+
+ mutex_unlock(&dev->struct_mutex);
}
/**