Skip to content

Commit

Permalink
Merge tag 'drm-intel-fixes-2018-12-12-1' of git://anongit.freedesktop…
Browse files Browse the repository at this point in the history
….org/drm/drm-intel into drm-fixes

- Two fixes to avoid GPU hangs (on Braswell and Gen3)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181212134010.GA18900@jlahtine-desk.ger.corp.intel.com
  • Loading branch information
airlied committed Dec 12, 2018
2 parents 71fb553 + 5b2e312 commit ce07fe9
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 97 deletions.
7 changes: 7 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2150,6 +2150,8 @@ struct drm_i915_private {
struct delayed_work idle_work;

ktime_t last_init_time;

struct i915_vma *scratch;
} gt;

/* perform PHY state sanity checks? */
Expand Down Expand Up @@ -3872,4 +3874,9 @@ static inline int intel_hws_csb_write_index(struct drm_i915_private *i915)
return I915_HWS_CSB_WRITE_INDEX;
}

static inline u32 i915_scratch_offset(const struct drm_i915_private *i915)
{
return i915_ggtt_offset(i915->gt.scratch);
}

#endif
50 changes: 49 additions & 1 deletion drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -5500,6 +5500,44 @@ static int __intel_engines_record_defaults(struct drm_i915_private *i915)
goto out_ctx;
}

static int
i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size)
{
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
int ret;

obj = i915_gem_object_create_stolen(i915, size);
if (!obj)
obj = i915_gem_object_create_internal(i915, size);
if (IS_ERR(obj)) {
DRM_ERROR("Failed to allocate scratch page\n");
return PTR_ERR(obj);
}

vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err_unref;
}

ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
if (ret)
goto err_unref;

i915->gt.scratch = vma;
return 0;

err_unref:
i915_gem_object_put(obj);
return ret;
}

static void i915_gem_fini_scratch(struct drm_i915_private *i915)
{
i915_vma_unpin_and_release(&i915->gt.scratch, 0);
}

int i915_gem_init(struct drm_i915_private *dev_priv)
{
int ret;
Expand Down Expand Up @@ -5546,12 +5584,19 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
goto err_unlock;
}

ret = i915_gem_contexts_init(dev_priv);
ret = i915_gem_init_scratch(dev_priv,
IS_GEN2(dev_priv) ? SZ_256K : PAGE_SIZE);
if (ret) {
GEM_BUG_ON(ret == -EIO);
goto err_ggtt;
}

ret = i915_gem_contexts_init(dev_priv);
if (ret) {
GEM_BUG_ON(ret == -EIO);
goto err_scratch;
}

ret = intel_engines_init(dev_priv);
if (ret) {
GEM_BUG_ON(ret == -EIO);
Expand Down Expand Up @@ -5624,6 +5669,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
err_context:
if (ret != -EIO)
i915_gem_contexts_fini(dev_priv);
err_scratch:
i915_gem_fini_scratch(dev_priv);
err_ggtt:
err_unlock:
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
Expand Down Expand Up @@ -5675,6 +5722,7 @@ void i915_gem_fini(struct drm_i915_private *dev_priv)
intel_uc_fini(dev_priv);
i915_gem_cleanup_engines(dev_priv);
i915_gem_contexts_fini(dev_priv);
i915_gem_fini_scratch(dev_priv);
mutex_unlock(&dev_priv->drm.struct_mutex);

intel_wa_list_free(&dev_priv->gt_wa_list);
Expand Down
7 changes: 1 addition & 6 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ relocate_entry(struct i915_vma *vma,
else if (gen >= 4)
len = 4;
else
len = 6;
len = 3;

batch = reloc_gpu(eb, vma, len);
if (IS_ERR(batch))
Expand Down Expand Up @@ -1309,11 +1309,6 @@ relocate_entry(struct i915_vma *vma,
*batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
*batch++ = addr;
*batch++ = target_offset;

/* And again for good measure (blb/pnv) */
*batch++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
*batch++ = addr;
*batch++ = target_offset;
}

goto out;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/i915/i915_gpu_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@ static void gem_record_rings(struct i915_gpu_state *error)
if (HAS_BROKEN_CS_TLB(i915))
ee->wa_batchbuffer =
i915_error_object_create(i915,
engine->scratch);
i915->gt.scratch);
request_record_user_bo(request, ee);

ee->ctx =
Expand Down
42 changes: 0 additions & 42 deletions drivers/gpu/drm/i915/intel_engine_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,46 +490,6 @@ void intel_engine_setup_common(struct intel_engine_cs *engine)
intel_engine_init_cmd_parser(engine);
}

int intel_engine_create_scratch(struct intel_engine_cs *engine,
unsigned int size)
{
struct drm_i915_gem_object *obj;
struct i915_vma *vma;
int ret;

WARN_ON(engine->scratch);

obj = i915_gem_object_create_stolen(engine->i915, size);
if (!obj)
obj = i915_gem_object_create_internal(engine->i915, size);
if (IS_ERR(obj)) {
DRM_ERROR("Failed to allocate scratch page\n");
return PTR_ERR(obj);
}

vma = i915_vma_instance(obj, &engine->i915->ggtt.vm, NULL);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err_unref;
}

ret = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH);
if (ret)
goto err_unref;

engine->scratch = vma;
return 0;

err_unref:
i915_gem_object_put(obj);
return ret;
}

void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
{
i915_vma_unpin_and_release(&engine->scratch, 0);
}

static void cleanup_status_page(struct intel_engine_cs *engine)
{
if (HWS_NEEDS_PHYSICAL(engine->i915)) {
Expand Down Expand Up @@ -704,8 +664,6 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
{
struct drm_i915_private *i915 = engine->i915;

intel_engine_cleanup_scratch(engine);

cleanup_status_page(engine);

intel_engine_fini_breadcrumbs(engine);
Expand Down
26 changes: 12 additions & 14 deletions drivers/gpu/drm/i915/intel_lrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,13 @@ static u64 execlists_update_context(struct i915_request *rq)
* may not be visible to the HW prior to the completion of the UC
* register write and that we may begin execution from the context
* before its image is complete leading to invalid PD chasing.
*
* Furthermore, Braswell, at least, wants a full mb to be sure that
* the writes are coherent in memory (visible to the GPU) prior to
* execution, and not just visible to other CPUs (as is the result of
* wmb).
*/
wmb();
mb();
return ce->lrc_desc;
}

Expand Down Expand Up @@ -1443,9 +1448,10 @@ static int execlists_request_alloc(struct i915_request *request)
static u32 *
gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)
{
/* NB no one else is allowed to scribble over scratch + 256! */
*batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
*batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
*batch++ = i915_ggtt_offset(engine->scratch) + 256;
*batch++ = i915_scratch_offset(engine->i915) + 256;
*batch++ = 0;

*batch++ = MI_LOAD_REGISTER_IMM(1);
Expand All @@ -1459,7 +1465,7 @@ gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch)

*batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT;
*batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4);
*batch++ = i915_ggtt_offset(engine->scratch) + 256;
*batch++ = i915_scratch_offset(engine->i915) + 256;
*batch++ = 0;

return batch;
Expand Down Expand Up @@ -1496,7 +1502,7 @@ static u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
PIPE_CONTROL_GLOBAL_GTT_IVB |
PIPE_CONTROL_CS_STALL |
PIPE_CONTROL_QW_WRITE,
i915_ggtt_offset(engine->scratch) +
i915_scratch_offset(engine->i915) +
2 * CACHELINE_BYTES);

*batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE;
Expand Down Expand Up @@ -1573,7 +1579,7 @@ static u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
PIPE_CONTROL_GLOBAL_GTT_IVB |
PIPE_CONTROL_CS_STALL |
PIPE_CONTROL_QW_WRITE,
i915_ggtt_offset(engine->scratch)
i915_scratch_offset(engine->i915)
+ 2 * CACHELINE_BYTES);
}

Expand Down Expand Up @@ -2141,7 +2147,7 @@ static int gen8_emit_flush_render(struct i915_request *request,
{
struct intel_engine_cs *engine = request->engine;
u32 scratch_addr =
i915_ggtt_offset(engine->scratch) + 2 * CACHELINE_BYTES;
i915_scratch_offset(engine->i915) + 2 * CACHELINE_BYTES;
bool vf_flush_wa = false, dc_flush_wa = false;
u32 *cs, flags = 0;
int len;
Expand Down Expand Up @@ -2478,10 +2484,6 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
if (ret)
return ret;

ret = intel_engine_create_scratch(engine, PAGE_SIZE);
if (ret)
goto err_cleanup_common;

ret = intel_init_workaround_bb(engine);
if (ret) {
/*
Expand All @@ -2496,10 +2498,6 @@ int logical_render_ring_init(struct intel_engine_cs *engine)
intel_engine_init_workarounds(engine);

return 0;

err_cleanup_common:
intel_engine_cleanup_common(engine);
return ret;
}

int logical_xcs_ring_init(struct intel_engine_cs *engine)
Expand Down
Loading

0 comments on commit ce07fe9

Please sign in to comment.