Commit d9d117e4 authored by Chris Wilson's avatar Chris Wilson

drm/i915/ringbuffer: Serialize load of PD_DIR

After triggering the mm switch with a load of PD_DIR, which may be
deferred unto the MI_SET_CONTEXT on rcs, serialise the next commands
with that load by posting a read of PD_DIR (or else those subsequent
commands may access the stale page tables).
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180611171825.13678-2-chris@chris-wilson.co.uk
parent 68a85703
...@@ -499,7 +499,8 @@ void intel_engine_setup_common(struct intel_engine_cs *engine) ...@@ -499,7 +499,8 @@ void intel_engine_setup_common(struct intel_engine_cs *engine)
intel_engine_init_cmd_parser(engine); intel_engine_init_cmd_parser(engine);
} }
int intel_engine_create_scratch(struct intel_engine_cs *engine, int size) int intel_engine_create_scratch(struct intel_engine_cs *engine,
unsigned int size)
{ {
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct i915_vma *vma; struct i915_vma *vma;
...@@ -533,7 +534,7 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, int size) ...@@ -533,7 +534,7 @@ int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
return ret; return ret;
} }
static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine) void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
{ {
i915_vma_unpin_and_release(&engine->scratch); i915_vma_unpin_and_release(&engine->scratch);
} }
......
...@@ -1361,8 +1361,9 @@ intel_ring_context_pin(struct intel_engine_cs *engine, ...@@ -1361,8 +1361,9 @@ intel_ring_context_pin(struct intel_engine_cs *engine,
static int intel_init_ring_buffer(struct intel_engine_cs *engine) static int intel_init_ring_buffer(struct intel_engine_cs *engine)
{ {
struct intel_ring *ring;
struct i915_timeline *timeline; struct i915_timeline *timeline;
struct intel_ring *ring;
unsigned int size;
int err; int err;
intel_engine_setup_common(engine); intel_engine_setup_common(engine);
...@@ -1388,12 +1389,21 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine) ...@@ -1388,12 +1389,21 @@ static int intel_init_ring_buffer(struct intel_engine_cs *engine)
GEM_BUG_ON(engine->buffer); GEM_BUG_ON(engine->buffer);
engine->buffer = ring; engine->buffer = ring;
err = intel_engine_init_common(engine); size = PAGE_SIZE;
if (HAS_BROKEN_CS_TLB(engine->i915))
size = I830_WA_SIZE;
err = intel_engine_create_scratch(engine, size);
if (err) if (err)
goto err_unpin; goto err_unpin;
err = intel_engine_init_common(engine);
if (err)
goto err_scratch;
return 0; return 0;
err_scratch:
intel_engine_cleanup_scratch(engine);
err_unpin: err_unpin:
intel_ring_unpin(ring); intel_ring_unpin(ring);
err_ring: err_ring:
...@@ -1455,6 +1465,25 @@ static int load_pd_dir(struct i915_request *rq, ...@@ -1455,6 +1465,25 @@ static int load_pd_dir(struct i915_request *rq,
return 0; return 0;
} }
static int flush_pd_dir(struct i915_request *rq)
{
const struct intel_engine_cs * const engine = rq->engine;
u32 *cs;
cs = intel_ring_begin(rq, 4);
if (IS_ERR(cs))
return PTR_ERR(cs);
/* Stall until the page table load is complete */
*cs++ = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
*cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
*cs++ = i915_ggtt_offset(engine->scratch);
*cs++ = MI_NOOP;
intel_ring_advance(rq, cs);
return 0;
}
static inline int mi_set_context(struct i915_request *rq, u32 flags) static inline int mi_set_context(struct i915_request *rq, u32 flags)
{ {
struct drm_i915_private *i915 = rq->i915; struct drm_i915_private *i915 = rq->i915;
...@@ -1638,6 +1667,12 @@ static int switch_context(struct i915_request *rq) ...@@ -1638,6 +1667,12 @@ static int switch_context(struct i915_request *rq)
goto err_mm; goto err_mm;
} }
if (ppgtt) {
ret = flush_pd_dir(rq);
if (ret)
goto err_mm;
}
if (ctx->remap_slice) { if (ctx->remap_slice) {
for (i = 0; i < MAX_L3_SLICES; i++) { for (i = 0; i < MAX_L3_SLICES; i++) {
if (!(ctx->remap_slice & BIT(i))) if (!(ctx->remap_slice & BIT(i)))
...@@ -2158,16 +2193,6 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine) ...@@ -2158,16 +2193,6 @@ int intel_init_render_ring_buffer(struct intel_engine_cs *engine)
if (ret) if (ret)
return ret; return ret;
if (INTEL_GEN(dev_priv) >= 6) {
ret = intel_engine_create_scratch(engine, PAGE_SIZE);
if (ret)
return ret;
} else if (HAS_BROKEN_CS_TLB(dev_priv)) {
ret = intel_engine_create_scratch(engine, I830_WA_SIZE);
if (ret)
return ret;
}
return 0; return 0;
} }
......
...@@ -869,9 +869,12 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno); ...@@ -869,9 +869,12 @@ void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno);
void intel_engine_setup_common(struct intel_engine_cs *engine); void intel_engine_setup_common(struct intel_engine_cs *engine);
int intel_engine_init_common(struct intel_engine_cs *engine); int intel_engine_init_common(struct intel_engine_cs *engine);
int intel_engine_create_scratch(struct intel_engine_cs *engine, int size);
void intel_engine_cleanup_common(struct intel_engine_cs *engine); void intel_engine_cleanup_common(struct intel_engine_cs *engine);
int intel_engine_create_scratch(struct intel_engine_cs *engine,
unsigned int size);
void intel_engine_cleanup_scratch(struct intel_engine_cs *engine);
int intel_init_render_ring_buffer(struct intel_engine_cs *engine); int intel_init_render_ring_buffer(struct intel_engine_cs *engine);
int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine); int intel_init_bsd_ring_buffer(struct intel_engine_cs *engine);
int intel_init_blt_ring_buffer(struct intel_engine_cs *engine); int intel_init_blt_ring_buffer(struct intel_engine_cs *engine);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment