Commit f4e15af7 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Mark the context state as dirty/written

In the next few patches, we will want to both copy out of the context
image and write a valid image into a new context. To be completely safe,
we should then couple in our domain tracking to ensure that we don't
have any issues with stale data remaining in unwanted cachelines.

Historically, we omitted the .write=true from the call to set-gtt-domain
in i915_switch_context() in order to avoid a stall between every request
as we would want to wait for the previous context write from the gpu.
Since then, we limit the set-gtt-domain to only occur when we first bind
the vma, so once in use we will never stall, and we are sure to flush
the context following a load from swap.

Equally we never applied the lessons learnt from ringbuffer submission
to execlists; so time to apply the flush of the lrc after load as well.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Acked-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171110142634.10551-6-chris@chris-wilson.co.uk
parent d378a3ef
...@@ -1077,12 +1077,34 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) ...@@ -1077,12 +1077,34 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
spin_unlock_irq(&engine->timeline->lock); spin_unlock_irq(&engine->timeline->lock);
} }
static int __context_pin(struct i915_gem_context *ctx, struct i915_vma *vma)
{
unsigned int flags;
int err;
/*
* Clear this page out of any CPU caches for coherent swap-in/out.
* We only want to do this on the first bind so that we do not stall
* on an active context (which by nature is already on the GPU).
*/
if (!(vma->flags & I915_VMA_GLOBAL_BIND)) {
err = i915_gem_object_set_to_gtt_domain(vma->obj, true);
if (err)
return err;
}
flags = PIN_GLOBAL | PIN_HIGH;
if (ctx->ggtt_offset_bias)
flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias;
return i915_vma_pin(vma, 0, GEN8_LR_CONTEXT_ALIGN, flags);
}
static struct intel_ring * static struct intel_ring *
execlists_context_pin(struct intel_engine_cs *engine, execlists_context_pin(struct intel_engine_cs *engine,
struct i915_gem_context *ctx) struct i915_gem_context *ctx)
{ {
struct intel_context *ce = &ctx->engine[engine->id]; struct intel_context *ce = &ctx->engine[engine->id];
unsigned int flags;
void *vaddr; void *vaddr;
int ret; int ret;
...@@ -1099,11 +1121,7 @@ execlists_context_pin(struct intel_engine_cs *engine, ...@@ -1099,11 +1121,7 @@ execlists_context_pin(struct intel_engine_cs *engine,
} }
GEM_BUG_ON(!ce->state); GEM_BUG_ON(!ce->state);
flags = PIN_GLOBAL | PIN_HIGH; ret = __context_pin(ctx, ce->state);
if (ctx->ggtt_offset_bias)
flags |= PIN_OFFSET_BIAS | ctx->ggtt_offset_bias;
ret = i915_vma_pin(ce->state, 0, GEN8_LR_CONTEXT_ALIGN, flags);
if (ret) if (ret)
goto err; goto err;
...@@ -1123,9 +1141,7 @@ execlists_context_pin(struct intel_engine_cs *engine, ...@@ -1123,9 +1141,7 @@ execlists_context_pin(struct intel_engine_cs *engine,
ce->lrc_reg_state[CTX_RING_BUFFER_START+1] = ce->lrc_reg_state[CTX_RING_BUFFER_START+1] =
i915_ggtt_offset(ce->ring->vma); i915_ggtt_offset(ce->ring->vma);
ce->state->obj->mm.dirty = true;
ce->state->obj->pin_global++; ce->state->obj->pin_global++;
i915_gem_context_get(ctx); i915_gem_context_get(ctx);
out: out:
return ce->ring; return ce->ring;
......
...@@ -1363,12 +1363,13 @@ static int context_pin(struct i915_gem_context *ctx) ...@@ -1363,12 +1363,13 @@ static int context_pin(struct i915_gem_context *ctx)
struct i915_vma *vma = ctx->engine[RCS].state; struct i915_vma *vma = ctx->engine[RCS].state;
int ret; int ret;
/* Clear this page out of any CPU caches for coherent swap-in/out. /*
* Clear this page out of any CPU caches for coherent swap-in/out.
* We only want to do this on the first bind so that we do not stall * We only want to do this on the first bind so that we do not stall
* on an active context (which by nature is already on the GPU). * on an active context (which by nature is already on the GPU).
*/ */
if (!(vma->flags & I915_VMA_GLOBAL_BIND)) { if (!(vma->flags & I915_VMA_GLOBAL_BIND)) {
ret = i915_gem_object_set_to_gtt_domain(vma->obj, false); ret = i915_gem_object_set_to_gtt_domain(vma->obj, true);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -1445,7 +1446,6 @@ intel_ring_context_pin(struct intel_engine_cs *engine, ...@@ -1445,7 +1446,6 @@ intel_ring_context_pin(struct intel_engine_cs *engine,
if (ret) if (ret)
goto err; goto err;
ce->state->obj->mm.dirty = true;
ce->state->obj->pin_global++; ce->state->obj->pin_global++;
} }
......
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