diff mbox

[3/4] drm/i915: Add the CPU mapping of the hw context to the pinned items.

Message ID 1444143124-16030-4-git-send-email-nicholas.hoath@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Nick Hoath Oct. 6, 2015, 2:52 p.m. UTC
Pin the hw ctx mapping so that it is not mapped/unmapped per bb
when doing GuC submission.

Issue: VIZ-4277
Cc: David Gordon <david.s.gordon@intel.com>
Signed-off-by: Nick Hoath <nicholas.hoath@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++------
 drivers/gpu/drm/i915/i915_drv.h     |  4 ++-
 drivers/gpu/drm/i915/intel_lrc.c    | 56 +++++++++++++++++++++++++++----------
 3 files changed, 50 insertions(+), 24 deletions(-)

Comments

Daniel Vetter Oct. 7, 2015, 4:08 p.m. UTC | #1
On Tue, Oct 06, 2015 at 03:52:03PM +0100, Nick Hoath wrote:
> Pin the hw ctx mapping so that it is not mapped/unmapped per bb
> when doing GuC submission.
> 
> Issue: VIZ-4277
> Cc: David Gordon <david.s.gordon@intel.com>
> Signed-off-by: Nick Hoath <nicholas.hoath@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_debugfs.c | 14 ++++------
>  drivers/gpu/drm/i915/i915_drv.h     |  4 ++-
>  drivers/gpu/drm/i915/intel_lrc.c    | 56 +++++++++++++++++++++++++++----------
>  3 files changed, 50 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 3f2a7a7..e68cf5fa 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -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);
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index d660ee3..b49fd12 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -879,8 +879,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];
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index b807928..55a4de56 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -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;
>  }
>  
> @@ -1004,7 +999,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)
>  {
> @@ -1051,7 +1070,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;
>  	}
> @@ -1915,6 +1934,8 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
>  
>  static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring)
>  {
> +	struct page *page;
> +	uint32_t *reg_state;
>  	int ret;
>  
>  	/* Intentionally left blank. */
> @@ -1939,6 +1960,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);
> @@ -1949,6 +1971,13 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
>  		return ret;
>  	}
>  
> +	page = i915_gem_object_get_page(
> +			ring->default_context->engine[ring->id].state,
> +			LRC_STATE_PN);
> +	reg_state = kmap(page);
> +	ring->default_context->engine[ring->id].reg_state = reg_state;
> +	ring->default_context->engine[ring->id].page = page;
> +
>  	return ret;
>  }
>  
> @@ -2388,6 +2417,7 @@ void intel_lr_context_free(struct intel_context *ctx)
>  			struct intel_engine_cs *ring = ringbuf->ring;
>  
>  			if (ctx == ring->default_context) {
> +				kunmap(ctx->engine[ring->id].page);

This shouldn't be necessary, the generic vma unbind hook should take care
of this like for other objects too. Or did I miss something?
-Daniel

>  				i915_gem_object_ggtt_unpin(ringbuf->obj);
>  				i915_gem_object_ggtt_unpin(ctx_obj);
>  			}
> @@ -2489,6 +2519,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;
>  
> @@ -2536,7 +2568,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;
> @@ -2545,14 +2576,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;
>  
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 3f2a7a7..e68cf5fa 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -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);
 		}
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d660ee3..b49fd12 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -879,8 +879,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];
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index b807928..55a4de56 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -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;
 }
 
@@ -1004,7 +999,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)
 {
@@ -1051,7 +1070,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;
 	}
@@ -1915,6 +1934,8 @@  void intel_logical_ring_cleanup(struct intel_engine_cs *ring)
 
 static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring)
 {
+	struct page *page;
+	uint32_t *reg_state;
 	int ret;
 
 	/* Intentionally left blank. */
@@ -1939,6 +1960,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);
@@ -1949,6 +1971,13 @@  static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin
 		return ret;
 	}
 
+	page = i915_gem_object_get_page(
+			ring->default_context->engine[ring->id].state,
+			LRC_STATE_PN);
+	reg_state = kmap(page);
+	ring->default_context->engine[ring->id].reg_state = reg_state;
+	ring->default_context->engine[ring->id].page = page;
+
 	return ret;
 }
 
@@ -2388,6 +2417,7 @@  void intel_lr_context_free(struct intel_context *ctx)
 			struct intel_engine_cs *ring = ringbuf->ring;
 
 			if (ctx == ring->default_context) {
+				kunmap(ctx->engine[ring->id].page);
 				i915_gem_object_ggtt_unpin(ringbuf->obj);
 				i915_gem_object_ggtt_unpin(ctx_obj);
 			}
@@ -2489,6 +2519,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;
 
@@ -2536,7 +2568,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;
@@ -2545,14 +2576,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;