aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2016-01-15 12:12:45 -0500
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>2016-01-18 04:58:44 -0500
commit82352e908acd36d7244c75a008c9f27a2ced44d5 (patch)
tree0dfab70e4ff5de1ebf0d15fb78b4dced5e5796e1
parent0eb973d31d0aadb6bc801fd6d796afecbbfc3d5b (diff)
drm/i915: Cache LRC state page in the context
LRC lifetime is well defined so we can cache the page pointing to the object backing store in the context in order to avoid walking over the object SG page list from the interrupt context without the big lock held. v2: Also cache the mapping. (Chris Wilson) v3: Unmap on the error path. v4: No need to cache the page. (Chris Wilson) v5: No need to dirty the page on unpin. (Chris Wilson) v6: kmap() cannot fail and use kmap_to_page to simplify unpin. (Chris Wilson) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Dave Gordon <david.s.gordon@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Link: http://patchwork.freedesktop.org/patch/msgid/1452877965-32042-1-git-send-email-tvrtko.ursulin@linux.intel.com
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c39
2 files changed, 22 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index acff98b9c148..af301482e6f8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -890,6 +890,7 @@ struct intel_context {
890 int pin_count; 890 int pin_count;
891 struct i915_vma *lrc_vma; 891 struct i915_vma *lrc_vma;
892 u64 lrc_desc; 892 u64 lrc_desc;
893 uint32_t *lrc_reg_state;
893 } engine[I915_NUM_RINGS]; 894 } engine[I915_NUM_RINGS];
894 895
895 struct list_head link; 896 struct list_head link;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 588cad58a196..faaf49077fea 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -390,14 +390,7 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
390{ 390{
391 struct intel_engine_cs *ring = rq->ring; 391 struct intel_engine_cs *ring = rq->ring;
392 struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt; 392 struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
393 struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; 393 uint32_t *reg_state = rq->ctx->engine[ring->id].lrc_reg_state;
394 struct page *page;
395 uint32_t *reg_state;
396
397 BUG_ON(!ctx_obj);
398
399 page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN);
400 reg_state = kmap_atomic(page);
401 394
402 reg_state[CTX_RING_TAIL+1] = rq->tail; 395 reg_state[CTX_RING_TAIL+1] = rq->tail;
403 reg_state[CTX_RING_BUFFER_START+1] = rq->ringbuf->vma->node.start; 396 reg_state[CTX_RING_BUFFER_START+1] = rq->ringbuf->vma->node.start;
@@ -414,8 +407,6 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
414 ASSIGN_CTX_PDP(ppgtt, reg_state, 0); 407 ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
415 } 408 }
416 409
417 kunmap_atomic(reg_state);
418
419 return 0; 410 return 0;
420} 411}
421 412
@@ -1067,6 +1058,7 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring,
1067 struct drm_i915_private *dev_priv = dev->dev_private; 1058 struct drm_i915_private *dev_priv = dev->dev_private;
1068 struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state; 1059 struct drm_i915_gem_object *ctx_obj = ctx->engine[ring->id].state;
1069 struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; 1060 struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf;
1061 struct page *lrc_state_page;
1070 int ret; 1062 int ret;
1071 1063
1072 WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); 1064 WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
@@ -1076,12 +1068,19 @@ static int intel_lr_context_do_pin(struct intel_engine_cs *ring,
1076 if (ret) 1068 if (ret)
1077 return ret; 1069 return ret;
1078 1070
1071 lrc_state_page = i915_gem_object_get_dirty_page(ctx_obj, LRC_STATE_PN);
1072 if (WARN_ON(!lrc_state_page)) {
1073 ret = -ENODEV;
1074 goto unpin_ctx_obj;
1075 }
1076
1079 ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf); 1077 ret = intel_pin_and_map_ringbuffer_obj(ring->dev, ringbuf);
1080 if (ret) 1078 if (ret)
1081 goto unpin_ctx_obj; 1079 goto unpin_ctx_obj;
1082 1080
1083 ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj); 1081 ctx->engine[ring->id].lrc_vma = i915_gem_obj_to_ggtt(ctx_obj);
1084 intel_lr_context_descriptor_update(ctx, ring); 1082 intel_lr_context_descriptor_update(ctx, ring);
1083 ctx->engine[ring->id].lrc_reg_state = kmap(lrc_state_page);
1085 ctx_obj->dirty = true; 1084 ctx_obj->dirty = true;
1086 1085
1087 /* Invalidate GuC TLB. */ 1086 /* Invalidate GuC TLB. */
@@ -1119,14 +1118,18 @@ void intel_lr_context_unpin(struct drm_i915_gem_request *rq)
1119 struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state; 1118 struct drm_i915_gem_object *ctx_obj = rq->ctx->engine[ring->id].state;
1120 struct intel_ringbuffer *ringbuf = rq->ringbuf; 1119 struct intel_ringbuffer *ringbuf = rq->ringbuf;
1121 1120
1122 if (ctx_obj) { 1121 WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex));
1123 WARN_ON(!mutex_is_locked(&ring->dev->struct_mutex)); 1122
1124 if (--rq->ctx->engine[ring->id].pin_count == 0) { 1123 if (!ctx_obj)
1125 intel_unpin_ringbuffer_obj(ringbuf); 1124 return;
1126 i915_gem_object_ggtt_unpin(ctx_obj); 1125
1127 rq->ctx->engine[ring->id].lrc_vma = NULL; 1126 if (--rq->ctx->engine[ring->id].pin_count == 0) {
1128 rq->ctx->engine[ring->id].lrc_desc = 0; 1127 kunmap(kmap_to_page(rq->ctx->engine[ring->id].lrc_reg_state));
1129 } 1128 intel_unpin_ringbuffer_obj(ringbuf);
1129 i915_gem_object_ggtt_unpin(ctx_obj);
1130 rq->ctx->engine[ring->id].lrc_vma = NULL;
1131 rq->ctx->engine[ring->id].lrc_desc = 0;
1132 rq->ctx->engine[ring->id].lrc_reg_state = NULL;
1130 } 1133 }
1131} 1134}
1132 1135