From cd5f42c2ef64826beb1a03d2c315ab0c407317f4 Mon Sep 17 00:00:00 2001 From: fritsch Date: Wed, 24 Dec 2014 23:09:46 +0100 Subject: [PATCH] Intel: Backport drm/i915: Disable PSMI sleep messages on all rings around context switches this drops the preliminary other gpu hang fixes --- .../3.17.7/linux-010-intel-fix-gpu-hang.patch | 152 ++++++++++++++++++ .../3.17.7/linux-010-intel-flush-flags.patch | 32 ---- .../linux-011-intel-pmsi-ctl-around-ctx.patch | 88 ---------- 3 files changed, 152 insertions(+), 120 deletions(-) create mode 100644 packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch delete mode 100644 packages/linux/patches/3.17.7/linux-010-intel-flush-flags.patch delete mode 100644 packages/linux/patches/3.17.7/linux-011-intel-pmsi-ctl-around-ctx.patch diff --git a/packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch b/packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch new file mode 100644 index 0000000000..638dbfbe38 --- /dev/null +++ b/packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch @@ -0,0 +1,152 @@ +commit 0da5fe8cc74e6aec119ea0cc56f3e2cc92caccec +Author: Chris Wilson +Date: Tue Dec 16 10:02:27 2014 +0000 + + drm/i915: Disable PSMI sleep messages on all rings around context switches + + There exists a current workaround to prevent a hang on context switch + should the ring go to sleep in the middle of the restore, + WaProgramMiArbOnOffAroundMiSetContext (applicable to all gen7+). In + spite of disabling arbitration (which prevents the ring from powering + down during the critical section) we were still hitting hangs that had + the hallmarks of the known erratum. That is we are still seeing hangs + "on the last instruction in the context restore". By comparing -nightly + (broken) with requests (working), we were able to deduce that it was the + semaphore LRI cross-talk that reproduced the original failure. The key + was that requests implemented deferred semaphore signalling, and + disabling that, i.e. emitting the semaphore signal to every other ring + after every batch restored the frequent hang. Explicitly disabling PSMI + sleep on the RCS ring was insufficient, all the rings had to be awake to + prevent the hangs. Fortunately, we can reduce the wakelock to the + MI_SET_CONTEXT operation itself, and so should be able to limit the extra + power implications. + + Since the MI_ARB_ON_OFF workaround is listed for all gen7 and above + products, we should apply this extra hammer for all of the same + platforms despite so far that we have only been able to reproduce the + hang on certain ivb and hsw models. The last question is whether we want + to always use the extra hammer or only when we know semaphores are in + operation. At the moment, we only use LRI on non-RCS rings for + semaphores, but that may change in the future with the possibility of + reintroducing this bug under subtle conditions. + + v2: Make it explicit that the PSMI LRI are an extension to the original + workaround for the other rings. + v3: Bikeshedding variable names and whitespacing + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80660 + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83677 + Cc: Simon Farnsworth + Cc: Daniel Vetter + Cc: Ville Syrjälä + Signed-off-by: Chris Wilson + Tested-by: Peter Frühberger + Reviewed-by: Daniel Vetter + Cc: stable@vger.kernel.org + Signed-off-by: Jani Nikula + + Backported to 3.17: + Signed-off-by: Ben Widawsky + + Conflicts: + drivers/gpu/drm/i915/i915_gem_context.c + +diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c +index 3b99390..7f76ea2 100644 +--- a/drivers/gpu/drm/i915/i915_gem_context.c ++++ b/drivers/gpu/drm/i915/i915_gem_context.c +@@ -563,7 +563,12 @@ mi_set_context(struct intel_engine_cs *ring, + struct intel_context *new_context, + u32 hw_flags) + { +- int ret; ++ const int num_rings = ++ /* Use an extended w/a on ivb+ if signalling from other rings */ ++ i915_semaphore_is_enabled(ring->dev) ? ++ hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 : ++ 0; ++ int len, i, ret; + + /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB + * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value +@@ -576,15 +581,30 @@ mi_set_context(struct intel_engine_cs *ring, + return ret; + } + +- ret = intel_ring_begin(ring, 6); ++ len = 4; ++ if (INTEL_INFO(ring->dev)->gen >= 7) ++ len += 2 + (num_rings ? 4*num_rings + 2 : 0); ++ ++ ret = intel_ring_begin(ring, len); + if (ret) + return ret; + + /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ +- if (INTEL_INFO(ring->dev)->gen >= 7) ++ if (INTEL_INFO(ring->dev)->gen >= 7) { + intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); +- else +- intel_ring_emit(ring, MI_NOOP); ++ if (num_rings) { ++ struct intel_engine_cs *signaller; ++ ++ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); ++ for_each_ring(signaller, to_i915(ring->dev), i) { ++ if (signaller == ring) ++ continue; ++ ++ intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); ++ intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); ++ } ++ } ++ } + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_SET_CONTEXT); +@@ -599,10 +619,21 @@ mi_set_context(struct intel_engine_cs *ring, + */ + intel_ring_emit(ring, MI_NOOP); + +- if (INTEL_INFO(ring->dev)->gen >= 7) ++ if (INTEL_INFO(ring->dev)->gen >= 7) { ++ if (num_rings) { ++ struct intel_engine_cs *signaller; ++ ++ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); ++ for_each_ring(signaller, to_i915(ring->dev), i) { ++ if (signaller == ring) ++ continue; ++ ++ intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); ++ intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); ++ } ++ } + intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); +- else +- intel_ring_emit(ring, MI_NOOP); ++ } + + intel_ring_advance(ring); + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index f29b44c..df02a15 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -1029,6 +1029,7 @@ enum punit_power_well { + #define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) + #define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) + #define GEN6_NOSYNC 0 ++#define RING_PSMI_CTL(base) ((base)+0x50) + #define RING_MAX_IDLE(base) ((base)+0x54) + #define RING_HWS_PGA(base) ((base)+0x80) + #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) +@@ -1354,6 +1355,7 @@ enum punit_power_well { + #define GEN6_BLITTER_FBC_NOTIFY (1<<3) + + #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 ++#define GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0) + #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) + #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) + + diff --git a/packages/linux/patches/3.17.7/linux-010-intel-flush-flags.patch b/packages/linux/patches/3.17.7/linux-010-intel-flush-flags.patch deleted file mode 100644 index 1550df8fba..0000000000 --- a/packages/linux/patches/3.17.7/linux-010-intel-flush-flags.patch +++ /dev/null @@ -1,32 +0,0 @@ -From aae8d9091ebefbb30c4e05f2c7d7c54c53a710e1 Mon Sep 17 00:00:00 2001 -From: root -Date: Wed, 10 Dec 2014 13:46:30 +0000 -Subject: [PATCH 1/2] flush-flags - ---- - drivers/gpu/drm/i915/intel_ringbuffer.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c -index 47a126a..fec60de 100644 ---- a/drivers/gpu/drm/i915/intel_ringbuffer.c -+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c -@@ -351,12 +351,15 @@ gen7_render_ring_flush(struct intel_engine_cs *ring, - flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; - flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; -+ flags |= 1 << 16; - /* - * TLB invalidate requires a post-sync write. - */ - flags |= PIPE_CONTROL_QW_WRITE; - flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; - -+ flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD; -+ - /* Workaround: we must issue a pipe_control with CS-stall bit - * set before a pipe_control command that has the state cache - * invalidate bit set. */ --- -1.9.1 - diff --git a/packages/linux/patches/3.17.7/linux-011-intel-pmsi-ctl-around-ctx.patch b/packages/linux/patches/3.17.7/linux-011-intel-pmsi-ctl-around-ctx.patch deleted file mode 100644 index 988de0e1d7..0000000000 --- a/packages/linux/patches/3.17.7/linux-011-intel-pmsi-ctl-around-ctx.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 21feaa695380e86bc8e3301038374a3a65c05540 Mon Sep 17 00:00:00 2001 -From: root -Date: Wed, 10 Dec 2014 13:47:00 +0000 -Subject: [PATCH 2/2] pmsi-ctl-around-ctx - -Conflicts: - drivers/gpu/drm/i915/i915_gem_context.c ---- - drivers/gpu/drm/i915/i915_gem_context.c | 25 +++++++++++++++++++++++-- - drivers/gpu/drm/i915/i915_reg.h | 2 ++ - 2 files changed, 25 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c -index 3b99390..9567ba6 100644 ---- a/drivers/gpu/drm/i915/i915_gem_context.c -+++ b/drivers/gpu/drm/i915/i915_gem_context.c -@@ -563,7 +563,10 @@ mi_set_context(struct intel_engine_cs *ring, - struct intel_context *new_context, - u32 hw_flags) - { -- int ret; -+ u32 flags = hw_flags | MI_MM_SPACE_GTT; -+ struct intel_engine_cs *engine; -+ int num_rings; -+ int ret, i; - - /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB - * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value -@@ -576,10 +579,22 @@ mi_set_context(struct intel_engine_cs *ring, - return ret; - } - -- ret = intel_ring_begin(ring, 6); -+ /* These flags are for resource streamer on HSW+ */ -+ if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8) -+ flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); -+ -+ num_rings = hweight32(INTEL_INFO(ring->dev)->ring_mask); -+ -+ ret = intel_ring_begin(ring, 6 + 2*(num_rings*2 + 1)); - if (ret) - return ret; - -+ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); -+ for_each_ring(engine, to_i915(ring->dev), i) { -+ intel_ring_emit(ring, RING_PSMI_CTL(engine->mmio_base)); -+ intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); -+ } -+ - /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ - if (INTEL_INFO(ring->dev)->gen >= 7) - intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); -@@ -604,6 +619,12 @@ mi_set_context(struct intel_engine_cs *ring, - else - intel_ring_emit(ring, MI_NOOP); - -+ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); -+ for_each_ring(engine, to_i915(ring->dev), i) { -+ intel_ring_emit(ring, RING_PSMI_CTL(engine->mmio_base)); -+ intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); -+ } -+ - intel_ring_advance(ring); - - return ret; -diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index f29b44c..df02a15 100644 ---- a/drivers/gpu/drm/i915/i915_reg.h -+++ b/drivers/gpu/drm/i915/i915_reg.h -@@ -1029,6 +1029,7 @@ enum punit_power_well { - #define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) - #define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) - #define GEN6_NOSYNC 0 -+#define RING_PSMI_CTL(base) ((base)+0x50) - #define RING_MAX_IDLE(base) ((base)+0x54) - #define RING_HWS_PGA(base) ((base)+0x80) - #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) -@@ -1354,6 +1355,7 @@ enum punit_power_well { - #define GEN6_BLITTER_FBC_NOTIFY (1<<3) - - #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 -+#define GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0) - #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) - #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) - --- -1.9.1 -