aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-08-07 08:19:19 -0400
committerJani Nikula <jani.nikula@intel.com>2017-08-21 04:52:35 -0400
commitd41a3c2be178783c85e05025265ab58fbb4d4ce1 (patch)
treefce8343d1c02f5ab1104ef8bbb89c46d62c0935b
parenta93c11527528c951b8d8db638162128a09e09ec2 (diff)
drm/i915: Clear lost context-switch interrupts across reset
During a global reset, we disable the irq. As we disable the irq, the hardware may be raising a GT interrupt that we then ignore, leaving it pending in the GTIIR. After the reset, we then re-enable the irq, triggering the pending interrupt. However, that interrupt was for the stale state from before the reset, and the contents of the CSB buffer are now invalid. v2: Add a comment to make it clear that the double clear is purely my paranoia. Reported-by: "Dong, Chuanxiao" <chuanxiao.dong@intel.com> Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: "Dong, Chuanxiao" <chuanxiao.dong@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Michal Winiarski <michal.winiarski@intel.com> Cc: Michel Thierry <michel.thierry@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170807121919.30165-1-chris@chris-wilson.co.uk Link: https://patchwork.freedesktop.org/patch/msgid/20170818090509.5363-1-chris@chris-wilson.co.uk Reviewed-by: Michel Thierry <michel.thierry@intel.com> (cherry picked from commit 64f09f00caf0a7cb40a8c0b85789bacba0f51d9e) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 7404cf2aac28..2afa4daa88e8 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1221,6 +1221,14 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
1221 return ret; 1221 return ret;
1222} 1222}
1223 1223
1224static u8 gtiir[] = {
1225 [RCS] = 0,
1226 [BCS] = 0,
1227 [VCS] = 1,
1228 [VCS2] = 1,
1229 [VECS] = 3,
1230};
1231
1224static int gen8_init_common_ring(struct intel_engine_cs *engine) 1232static int gen8_init_common_ring(struct intel_engine_cs *engine)
1225{ 1233{
1226 struct drm_i915_private *dev_priv = engine->i915; 1234 struct drm_i915_private *dev_priv = engine->i915;
@@ -1245,9 +1253,22 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
1245 1253
1246 DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name); 1254 DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
1247 1255
1248 /* After a GPU reset, we may have requests to replay */ 1256 GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
1257
1258 /*
1259 * Clear any pending interrupt state.
1260 *
1261 * We do it twice out of paranoia that some of the IIR are double
1262 * buffered, and if we only reset it once there may still be
1263 * an interrupt pending.
1264 */
1265 I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
1266 GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
1267 I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
1268 GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
1249 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); 1269 clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
1250 1270
1271 /* After a GPU reset, we may have requests to replay */
1251 submit = false; 1272 submit = false;
1252 for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { 1273 for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
1253 if (!port_isset(&port[n])) 1274 if (!port_isset(&port[n]))