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:821ed7df6e
("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 commit64f09f00ca
) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
This commit is contained in:
Родитель
a93c115275
Коммит
d41a3c2be1
|
@ -1221,6 +1221,14 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 gtiir[] = {
|
||||||
|
[RCS] = 0,
|
||||||
|
[BCS] = 0,
|
||||||
|
[VCS] = 1,
|
||||||
|
[VCS2] = 1,
|
||||||
|
[VECS] = 3,
|
||||||
|
};
|
||||||
|
|
||||||
static int gen8_init_common_ring(struct intel_engine_cs *engine)
|
static int gen8_init_common_ring(struct intel_engine_cs *engine)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = engine->i915;
|
struct drm_i915_private *dev_priv = engine->i915;
|
||||||
|
@ -1245,9 +1253,22 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
|
DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
|
||||||
|
|
||||||
/* After a GPU reset, we may have requests to replay */
|
GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear any pending interrupt state.
|
||||||
|
*
|
||||||
|
* We do it twice out of paranoia that some of the IIR are double
|
||||||
|
* buffered, and if we only reset it once there may still be
|
||||||
|
* an interrupt pending.
|
||||||
|
*/
|
||||||
|
I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
|
||||||
|
GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
|
||||||
|
I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
|
||||||
|
GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
|
||||||
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
|
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
|
||||||
|
|
||||||
|
/* After a GPU reset, we may have requests to replay */
|
||||||
submit = false;
|
submit = false;
|
||||||
for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
|
for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
|
||||||
if (!port_isset(&port[n]))
|
if (!port_isset(&port[n]))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче