aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-10-04 16:11:26 -0400
committerJani Nikula <jani.nikula@intel.com>2016-10-10 09:06:42 -0400
commitc79d7303e1ddc8260b0f385212b26cad297ff890 (patch)
treeb1b2afb65d9aa3f008e79fdddb43c0aa8700ada5 /drivers/gpu
parent27399eeec28ff33a0c5216a80cf57cbc6ba3c15e (diff)
drm/i915/execlists: Reinitialise context image after GPU hang
On Braswell, at least, we observe that the context image is written in multiple phases. The first phase is to clear the register state, and subsequently rewrite it. A GPU reset at the right moment can interrupt the context update leaving it corrupt, and our update of the RING_HEAD is not sufficient to restart the engine afterwards. To recover, we need to reset the registers back to their original values. The context state is lost. What we need is a better mechanism to serialise the reset with pending flushes from the GPU. Fixes: 821ed7df6e2a ("drm/i915: Update reset path to fix incomplete requests") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20161004201132.21801-2-chris@chris-wilson.co.uk (cherry picked from commit a3aabe86a3406b9946a4f7707762a833a58dfe9c) Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c103
1 files changed, 62 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 251143361f31..7da83330257d 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -226,10 +226,16 @@ enum {
226/* Typical size of the average request (2 pipecontrols and a MI_BB) */ 226/* Typical size of the average request (2 pipecontrols and a MI_BB) */
227#define EXECLISTS_REQUEST_SIZE 64 /* bytes */ 227#define EXECLISTS_REQUEST_SIZE 64 /* bytes */
228 228
229#define WA_TAIL_DWORDS 2
230
229static int execlists_context_deferred_alloc(struct i915_gem_context *ctx, 231static int execlists_context_deferred_alloc(struct i915_gem_context *ctx,
230 struct intel_engine_cs *engine); 232 struct intel_engine_cs *engine);
231static int intel_lr_context_pin(struct i915_gem_context *ctx, 233static int intel_lr_context_pin(struct i915_gem_context *ctx,
232 struct intel_engine_cs *engine); 234 struct intel_engine_cs *engine);
235static void execlists_init_reg_state(u32 *reg_state,
236 struct i915_gem_context *ctx,
237 struct intel_engine_cs *engine,
238 struct intel_ring *ring);
233 239
234/** 240/**
235 * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists 241 * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists
@@ -708,7 +714,6 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
708{ 714{
709 struct intel_context *ce = &ctx->engine[engine->id]; 715 struct intel_context *ce = &ctx->engine[engine->id];
710 void *vaddr; 716 void *vaddr;
711 u32 *lrc_reg_state;
712 int ret; 717 int ret;
713 718
714 lockdep_assert_held(&ctx->i915->drm.struct_mutex); 719 lockdep_assert_held(&ctx->i915->drm.struct_mutex);
@@ -727,17 +732,16 @@ static int intel_lr_context_pin(struct i915_gem_context *ctx,
727 goto unpin_vma; 732 goto unpin_vma;
728 } 733 }
729 734
730 lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
731
732 ret = intel_ring_pin(ce->ring); 735 ret = intel_ring_pin(ce->ring);
733 if (ret) 736 if (ret)
734 goto unpin_map; 737 goto unpin_map;
735 738
736 intel_lr_context_descriptor_update(ctx, engine); 739 intel_lr_context_descriptor_update(ctx, engine);
737 740
738 lrc_reg_state[CTX_RING_BUFFER_START+1] = 741 ce->lrc_reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
742 ce->lrc_reg_state[CTX_RING_BUFFER_START+1] =
739 i915_ggtt_offset(ce->ring->vma); 743 i915_ggtt_offset(ce->ring->vma);
740 ce->lrc_reg_state = lrc_reg_state; 744
741 ce->state->obj->dirty = true; 745 ce->state->obj->dirty = true;
742 746
743 /* Invalidate GuC TLB. */ 747 /* Invalidate GuC TLB. */
@@ -1289,8 +1293,21 @@ static void reset_common_ring(struct intel_engine_cs *engine,
1289 struct execlist_port *port = engine->execlist_port; 1293 struct execlist_port *port = engine->execlist_port;
1290 struct intel_context *ce = &request->ctx->engine[engine->id]; 1294 struct intel_context *ce = &request->ctx->engine[engine->id];
1291 1295
1296 /* We want a simple context + ring to execute the breadcrumb update.
1297 * We cannot rely on the context being intact across the GPU hang,
1298 * so clear it and rebuild just what we need for the breadcrumb.
1299 * All pending requests for this context will be zapped, and any
1300 * future request will be after userspace has had the opportunity
1301 * to recreate its own state.
1302 */
1303 execlists_init_reg_state(ce->lrc_reg_state,
1304 request->ctx, engine, ce->ring);
1305
1292 /* Move the RING_HEAD onto the breadcrumb, past the hanging batch */ 1306 /* Move the RING_HEAD onto the breadcrumb, past the hanging batch */
1307 ce->lrc_reg_state[CTX_RING_BUFFER_START+1] =
1308 i915_ggtt_offset(ce->ring->vma);
1293 ce->lrc_reg_state[CTX_RING_HEAD+1] = request->postfix; 1309 ce->lrc_reg_state[CTX_RING_HEAD+1] = request->postfix;
1310
1294 request->ring->head = request->postfix; 1311 request->ring->head = request->postfix;
1295 request->ring->last_retired_head = -1; 1312 request->ring->last_retired_head = -1;
1296 intel_ring_update_space(request->ring); 1313 intel_ring_update_space(request->ring);
@@ -1310,6 +1327,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
1310 GEM_BUG_ON(request->ctx != port[0].request->ctx); 1327 GEM_BUG_ON(request->ctx != port[0].request->ctx);
1311 port[0].count = 0; 1328 port[0].count = 0;
1312 port[1].count = 0; 1329 port[1].count = 0;
1330
1331 /* Reset WaIdleLiteRestore:bdw,skl as well */
1332 request->tail = request->wa_tail - WA_TAIL_DWORDS * sizeof(u32);
1313} 1333}
1314 1334
1315static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) 1335static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
@@ -1547,7 +1567,6 @@ static void bxt_a_seqno_barrier(struct intel_engine_cs *engine)
1547 * used as a workaround for not being allowed to do lite 1567 * used as a workaround for not being allowed to do lite
1548 * restore with HEAD==TAIL (WaIdleLiteRestore). 1568 * restore with HEAD==TAIL (WaIdleLiteRestore).
1549 */ 1569 */
1550#define WA_TAIL_DWORDS 2
1551 1570
1552static int gen8_emit_request(struct drm_i915_gem_request *request) 1571static int gen8_emit_request(struct drm_i915_gem_request *request)
1553{ 1572{
@@ -1894,38 +1913,13 @@ static u32 intel_lr_indirect_ctx_offset(struct intel_engine_cs *engine)
1894 return indirect_ctx_offset; 1913 return indirect_ctx_offset;
1895} 1914}
1896 1915
1897static int 1916static void execlists_init_reg_state(u32 *reg_state,
1898populate_lr_context(struct i915_gem_context *ctx, 1917 struct i915_gem_context *ctx,
1899 struct drm_i915_gem_object *ctx_obj, 1918 struct intel_engine_cs *engine,
1900 struct intel_engine_cs *engine, 1919 struct intel_ring *ring)
1901 struct intel_ring *ring)
1902{ 1920{
1903 struct drm_i915_private *dev_priv = ctx->i915; 1921 struct drm_i915_private *dev_priv = engine->i915;
1904 struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; 1922 struct i915_hw_ppgtt *ppgtt = ctx->ppgtt ?: dev_priv->mm.aliasing_ppgtt;
1905 void *vaddr;
1906 u32 *reg_state;
1907 int ret;
1908
1909 if (!ppgtt)
1910 ppgtt = dev_priv->mm.aliasing_ppgtt;
1911
1912 ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
1913 if (ret) {
1914 DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
1915 return ret;
1916 }
1917
1918 vaddr = i915_gem_object_pin_map(ctx_obj, I915_MAP_WB);
1919 if (IS_ERR(vaddr)) {
1920 ret = PTR_ERR(vaddr);
1921 DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret);
1922 return ret;
1923 }
1924 ctx_obj->dirty = true;
1925
1926 /* The second page of the context object contains some fields which must
1927 * be set up prior to the first execution. */
1928 reg_state = vaddr + LRC_STATE_PN * PAGE_SIZE;
1929 1923
1930 /* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM 1924 /* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM
1931 * commands followed by (reg, value) pairs. The values we are setting here are 1925 * commands followed by (reg, value) pairs. The values we are setting here are
@@ -1939,14 +1933,11 @@ populate_lr_context(struct i915_gem_context *ctx,
1939 _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH | 1933 _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH |
1940 CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT | 1934 CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT |
1941 (HAS_RESOURCE_STREAMER(dev_priv) ? 1935 (HAS_RESOURCE_STREAMER(dev_priv) ?
1942 CTX_CTRL_RS_CTX_ENABLE : 0))); 1936 CTX_CTRL_RS_CTX_ENABLE : 0)));
1943 ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(engine->mmio_base), 1937 ASSIGN_CTX_REG(reg_state, CTX_RING_HEAD, RING_HEAD(engine->mmio_base),
1944 0); 1938 0);
1945 ASSIGN_CTX_REG(reg_state, CTX_RING_TAIL, RING_TAIL(engine->mmio_base), 1939 ASSIGN_CTX_REG(reg_state, CTX_RING_TAIL, RING_TAIL(engine->mmio_base),
1946 0); 1940 0);
1947 /* Ring buffer start address is not known until the buffer is pinned.
1948 * It is written to the context image in execlists_update_context()
1949 */
1950 ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_START, 1941 ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_START,
1951 RING_START(engine->mmio_base), 0); 1942 RING_START(engine->mmio_base), 0);
1952 ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL, 1943 ASSIGN_CTX_REG(reg_state, CTX_RING_BUFFER_CONTROL,
@@ -2029,6 +2020,36 @@ populate_lr_context(struct i915_gem_context *ctx,
2029 ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE, 2020 ASSIGN_CTX_REG(reg_state, CTX_R_PWR_CLK_STATE, GEN8_R_PWR_CLK_STATE,
2030 make_rpcs(dev_priv)); 2021 make_rpcs(dev_priv));
2031 } 2022 }
2023}
2024
2025static int
2026populate_lr_context(struct i915_gem_context *ctx,
2027 struct drm_i915_gem_object *ctx_obj,
2028 struct intel_engine_cs *engine,
2029 struct intel_ring *ring)
2030{
2031 void *vaddr;
2032 int ret;
2033
2034 ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true);
2035 if (ret) {
2036 DRM_DEBUG_DRIVER("Could not set to CPU domain\n");
2037 return ret;
2038 }
2039
2040 vaddr = i915_gem_object_pin_map(ctx_obj, I915_MAP_WB);
2041 if (IS_ERR(vaddr)) {
2042 ret = PTR_ERR(vaddr);
2043 DRM_DEBUG_DRIVER("Could not map object pages! (%d)\n", ret);
2044 return ret;
2045 }
2046 ctx_obj->dirty = true;
2047
2048 /* The second page of the context object contains some fields which must
2049 * be set up prior to the first execution. */
2050
2051 execlists_init_reg_state(vaddr + LRC_STATE_PN * PAGE_SIZE,
2052 ctx, engine, ring);
2032 2053
2033 i915_gem_object_unpin_map(ctx_obj); 2054 i915_gem_object_unpin_map(ctx_obj);
2034 2055