Commit 9e60ab03 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Disable irqs across GPU reset

Whilst we reset the GPU, we want to prevent execlists from submitting
new work (which it does via an interrupt handler). To achieve this we
disable the irq (and drain the irq tasklet) around the reset. When we
enable it again afters, the interrupt queue should be empty and we can
reinitialise from a known state without fear of the tasklet running
concurrently.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161004201132.21801-4-chris@chris-wilson.co.uk
parent c87d50cc
...@@ -1728,6 +1728,21 @@ int i915_resume_switcheroo(struct drm_device *dev) ...@@ -1728,6 +1728,21 @@ int i915_resume_switcheroo(struct drm_device *dev)
return i915_drm_resume(dev); return i915_drm_resume(dev);
} }
static void disable_engines_irq(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
/* Ensure irq handler finishes, and not run again. */
disable_irq(dev_priv->drm.irq);
for_each_engine(engine, dev_priv)
tasklet_kill(&engine->irq_tasklet);
}
static void enable_engines_irq(struct drm_i915_private *dev_priv)
{
enable_irq(dev_priv->drm.irq);
}
/** /**
* i915_reset - reset chip after a hang * i915_reset - reset chip after a hang
* @dev: drm device to reset * @dev: drm device to reset
...@@ -1761,7 +1776,11 @@ void i915_reset(struct drm_i915_private *dev_priv) ...@@ -1761,7 +1776,11 @@ void i915_reset(struct drm_i915_private *dev_priv)
error->reset_count++; error->reset_count++;
pr_notice("drm/i915: Resetting chip after gpu hang\n"); pr_notice("drm/i915: Resetting chip after gpu hang\n");
disable_engines_irq(dev_priv);
ret = intel_gpu_reset(dev_priv, ALL_ENGINES); ret = intel_gpu_reset(dev_priv, ALL_ENGINES);
enable_engines_irq(dev_priv);
if (ret) { if (ret) {
if (ret != -ENODEV) if (ret != -ENODEV)
DRM_ERROR("Failed to reset chip: %i\n", ret); DRM_ERROR("Failed to reset chip: %i\n", ret);
......
...@@ -2581,8 +2581,6 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine) ...@@ -2581,8 +2581,6 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
struct i915_gem_context *incomplete_ctx; struct i915_gem_context *incomplete_ctx;
bool ring_hung; bool ring_hung;
/* Ensure irq handler finishes, and not run again. */
tasklet_kill(&engine->irq_tasklet);
if (engine->irq_seqno_barrier) if (engine->irq_seqno_barrier)
engine->irq_seqno_barrier(engine); engine->irq_seqno_barrier(engine);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment