mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-28 13:16:41 +00:00
Intel: Backport drm/i915: Disable PSMI sleep messages on all rings around context switches
this drops the preliminary other gpu hang fixes
This commit is contained in:
parent
4c41dd5830
commit
cd5f42c2ef
152
packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch
vendored
Normal file
152
packages/linux/patches/3.17.7/linux-010-intel-fix-gpu-hang.patch
vendored
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
commit 0da5fe8cc74e6aec119ea0cc56f3e2cc92caccec
|
||||||
|
Author: Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
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 <simon@farnz.org.uk>
|
||||||
|
Cc: Daniel Vetter <daniel@ffwll.ch>
|
||||||
|
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
|
||||||
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
Tested-by: Peter Frühberger <fritsch@xbmc.org>
|
||||||
|
Reviewed-by: Daniel Vetter <daniel@ffwll.ch>
|
||||||
|
Cc: stable@vger.kernel.org
|
||||||
|
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
|
||||||
|
|
||||||
|
Backported to 3.17:
|
||||||
|
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
From aae8d9091ebefbb30c4e05f2c7d7c54c53a710e1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: root <root@localhost.localdomain>
|
|
||||||
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
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
|||||||
From 21feaa695380e86bc8e3301038374a3a65c05540 Mon Sep 17 00:00:00 2001
|
|
||||||
From: root <root@localhost.localdomain>
|
|
||||||
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
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user