@@ -1970,10 +1970,9 @@ static int i915_context_status(struct seq_file *m, void *unused)
static void i915_dump_lrc_obj(struct seq_file *m,
struct intel_engine_cs *ring,
- struct drm_i915_gem_object *ctx_obj)
+ struct drm_i915_gem_object *ctx_obj,
+ uint32_t *reg_state)
{
- struct page *page;
- uint32_t *reg_state;
int j;
unsigned long ggtt_offset = 0;
@@ -1996,17 +1995,13 @@ static void i915_dump_lrc_obj(struct seq_file *m,
return;
}
- page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
- if (!WARN_ON(page == NULL)) {
- reg_state = kmap_atomic(page);
-
+ if (!WARN_ON(reg_state == NULL)) {
for (j = 0; j < 0x600 / sizeof(u32) / 4; j += 4) {
seq_printf(m, "\t[0x%08lx] 0x%08x 0x%08x 0x%08x 0x%08x\n",
ggtt_offset + 4096 + (j * 4),
reg_state[j], reg_state[j + 1],
reg_state[j + 2], reg_state[j + 3]);
}
- kunmap_atomic(reg_state);
}
seq_putc(m, '\n');
@@ -2034,7 +2029,8 @@ static int i915_dump_lrc(struct seq_file *m, void *unused)
for_each_ring(ring, dev_priv, i) {
if (ring->default_context != ctx)
i915_dump_lrc_obj(m, ring,
- ctx->engine[i].state);
+ ctx->engine[i].state,
+ ctx->engine[i].reg_state);
}
}
@@ -881,8 +881,10 @@ struct intel_context {
} legacy_hw_ctx;
/* Execlists */
- struct {
+ struct intel_context_engine {
struct drm_i915_gem_object *state;
+ uint32_t *reg_state;
+ struct page *page;
struct intel_ringbuffer *ringbuf;
int pin_count;
} engine[I915_NUM_RINGS];
@@ -360,16 +360,13 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state;
struct drm_i915_gem_object *rb_obj = rq->ringbuf->obj;
- struct page *page;
- uint32_t *reg_state;
+ uint32_t *reg_state = rq->ctx->engine[ring->id].reg_state;
BUG_ON(!ctx_obj);
+ WARN_ON(!reg_state);
WARN_ON(!i915_gem_obj_is_pinned(ctx_obj));
WARN_ON(!i915_gem_obj_is_pinned(rb_obj));
- page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
- reg_state = kmap_atomic(page);
-
reg_state[CTX_RING_TAIL+1] = rq->tail;
reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(rb_obj);
@@ -385,8 +382,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
}
- kunmap_atomic(reg_state);
-
return 0;
}
@@ -985,7 +980,31 @@ int logical_ring_flush_all_caches(struct drm_i915_gem_request *req)
return 0;
}
-static int intel_lr_context_do_pin(struct intel_engine_cs *ring,
+static int intel_mmap_hw_context(struct drm_i915_gem_object *obj,
+ bool unmap)
+{
+ int ret = 0;
+ struct intel_context_engine *ice =
+ (struct intel_context_engine *)obj->mappable;
+ struct page *page;
+ uint32_t *reg_state;
+
+ if (unmap) {
+ kunmap(ice->page);
+ ice->reg_state = NULL;
+ ice->page = NULL;
+ } else {
+ page = i915_gem_object_get_page(obj, LRC_STATE_PN);
+ reg_state = kmap(page);
+ ice->reg_state = reg_state;
+ ice->page = page;
+ }
+ return ret;
+}
+
+static int intel_lr_context_do_pin(
+ struct intel_context *ctx,
+ struct intel_engine_cs *ring,
struct drm_i915_gem_object *ctx_obj,
struct intel_ringbuffer *ringbuf)
{
@@ -1032,7 +1051,7 @@ static int intel_lr_context_pin(struct drm_i915_gem_request *rq)
struct intel_ringbuffer *ringbuf = rq->ringbuf;
if (rq->ctx->engine[ring->id].pin_count++ == 0) {
- ret = intel_lr_context_do_pin(ring, ctx_obj, ringbuf);
+ ret = intel_lr_context_do_pin(rq->ctx, ring, ctx_obj, ringbuf);
if (ret)
goto reset_pin_count;
}
@@ -1921,6 +1940,7 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
/* As this is the default context, always pin it */
ret = intel_lr_context_do_pin(
+ ring->default_context,
ring,
ring->default_context->engine[ring->id].state,
ring->default_context->engine[ring->id].ringbuf);
@@ -2471,6 +2491,8 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
goto error_ringbuf;
}
+ ctx_obj->mmap = intel_mmap_hw_context;
+ ctx_obj->mappable = &(ctx->engine[ring->id]);
ctx->engine[ring->id].ringbuf = ringbuf;
ctx->engine[ring->id].state = ctx_obj;
@@ -2518,7 +2540,6 @@ void intel_lr_context_reset(struct drm_device *dev,
struct intel_ringbuffer *ringbuf =
ctx->engine[ring->id].ringbuf;
uint32_t *reg_state;
- struct page *page;
if (!ctx_obj)
continue;
@@ -2527,14 +2548,11 @@ void intel_lr_context_reset(struct drm_device *dev,
WARN(1, "Failed get_pages for context obj\n");
continue;
}
- page = i915_gem_object_get_page(ctx_obj, LRC_STATE_PN);
- reg_state = kmap_atomic(page);
+ reg_state = ctx->engine[ring->id].reg_state;
reg_state[CTX_RING_HEAD+1] = 0;
reg_state[CTX_RING_TAIL+1] = 0;
- kunmap_atomic(reg_state);
-
ringbuf->head = 0;
ringbuf->tail = 0;
Pin the hw ctx mapping so that it is not mapped/unmapped per bb when doing GuC submission. v2: Removed interim development extra mapping. (Daniel Vetter) Issue: VIZ-4277 Signed-off-by: Nick Hoath <nicholas.hoath@intel.com> Cc: David Gordon <david.s.gordon@intel.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> --- drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++------- drivers/gpu/drm/i915/i915_drv.h | 4 +++- drivers/gpu/drm/i915/intel_lrc.c | 46 ++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 24 deletions(-)