diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-08-07 08:19:19 -0400 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2017-08-21 04:52:35 -0400 |
commit | d41a3c2be178783c85e05025265ab58fbb4d4ce1 (patch) | |
tree | fce8343d1c02f5ab1104ef8bbb89c46d62c0935b | |
parent | a93c11527528c951b8d8db638162128a09e09ec2 (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.c | 23 |
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 | ||
1224 | static u8 gtiir[] = { | ||
1225 | [RCS] = 0, | ||
1226 | [BCS] = 0, | ||
1227 | [VCS] = 1, | ||
1228 | [VCS2] = 1, | ||
1229 | [VECS] = 3, | ||
1230 | }; | ||
1231 | |||
1224 | static int gen8_init_common_ring(struct intel_engine_cs *engine) | 1232 | static 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])) |