Clean up lrc context init by: - Move context initialisation in to i915_gem_init_hw - Move one off initialisation for render ring to i915_gem_validate_context - Move default context initialisation to logical_ring_init Rename intel_lr_context_deferred_create to intel_lr_context_deferred_alloc, to reflect reduced functionality. Issue: VIZ-4798 Signed-off-by: Nick Hoath <nicholas.hoath@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 41 ++++++++---- drivers/gpu/drm/i915/i915_gem_context.c | 21 ------ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 36 +++++++++- drivers/gpu/drm/i915/intel_lrc.c | 101 ++++++++++------------------- drivers/gpu/drm/i915/intel_lrc.h | 6 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 8 files changed, 105 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ef02378..3142a3a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3063,7 +3063,6 @@ int __must_check i915_gem_context_init(struct drm_device *dev); void i915_gem_context_fini(struct drm_device *dev); void i915_gem_context_reset(struct drm_device *dev); int i915_gem_context_open(struct drm_device *dev, struct drm_file *file); -int i915_gem_context_enable(struct drm_i915_gem_request *req); void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); int i915_switch_context(struct drm_i915_gem_request *req); struct intel_context * diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d9f5e4d..914f660 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5048,6 +5048,7 @@ i915_gem_init_hw(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; int ret, i, j; + struct drm_i915_gem_request *req; if (INTEL_INFO(dev)->gen < 6 && !intel_enable_gtt()) return -EIO; @@ -5100,15 +5101,17 @@ i915_gem_init_hw(struct drm_device *dev) } /* Now it is safe to go back round and do everything else: */ - for_each_ring(ring, dev_priv, i) { - struct drm_i915_gem_request *req; + ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); + if (ret) + goto out; + + for_each_ring(ring, dev_priv, i) { WARN_ON(!ring->default_context); ret = i915_gem_request_alloc(ring, ring->default_context, &req); if (ret) { - i915_gem_cleanup_ringbuffer(dev); - goto out; + goto clean_ringbuf_out; } if (ring->id == RCS) { @@ -5119,22 +5122,34 @@ i915_gem_init_hw(struct drm_device *dev) ret = i915_ppgtt_init_ring(req); if (ret && ret != -EIO) { DRM_ERROR("PPGTT enable ring #%d failed %d\n", i, ret); - i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); - goto out; + goto clean_req_out; } - ret = i915_gem_context_enable(req); - if (ret && ret != -EIO) { - DRM_ERROR("Context enable ring #%d failed %d\n", i, ret); - i915_gem_request_cancel(req); - i915_gem_cleanup_ringbuffer(dev); - goto out; + if (ring->switch_context) { + ret = ring->switch_context(req); + if (ret && ret != -EIO) { + DRM_ERROR("ring switch context: %d\n", + ret); + goto clean_req_out; + } + } else if (ring->init_context) { + ret = ring->init_context(req); + if (ret && ret != -EIO) { + DRM_ERROR("ring init context: %d\n", + ret); + goto clean_req_out; + } } i915_add_request_no_flush(req); } + return ret; + +clean_req_out: + i915_gem_request_cancel(req); +clean_ringbuf_out: + i915_gem_cleanup_ringbuffer(dev); out: intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index a7e58a8..87a7fbc 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -409,27 +409,6 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_context_unreference(dctx); } -int i915_gem_context_enable(struct drm_i915_gem_request *req) -{ - struct intel_engine_cs *ring = req->ring; - int ret; - - if (i915.enable_execlists) { - if (ring->init_context == NULL) - return 0; - - ret = ring->init_context(req); - } else - ret = i915_switch_context(req); - - if (ret) { - DRM_ERROR("ring init context: %d\n", ret); - return ret; - } - - return 0; -} - static int context_idr_cleanup(int id, void *p, void *data) { struct intel_context *ctx = p; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 600db74..5455e35 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -993,6 +993,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, { struct intel_context *ctx = NULL; struct i915_ctx_hang_stats *hs; + int ret; if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE) return ERR_PTR(-EINVAL); @@ -1008,14 +1009,47 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, } if (i915.enable_execlists && !ctx->engine[ring->id].state) { - int ret = intel_lr_context_deferred_create(ctx, ring); + ret = intel_lr_context_deferred_alloc(ctx, ring); if (ret) { DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret); return ERR_PTR(ret); } + + if (ring->id == RCS && !ctx->rcs_initialized) { + if (ring->init_context) { + struct drm_i915_gem_request *req; + + ret = i915_gem_request_alloc(ring, + ring->default_context, &req); + if (ret) { + DRM_ERROR("ring create req: %d\n", + ret); + i915_gem_request_cancel(req); + goto validate_error; + } + + ret = ring->init_context(req); + if (ret) { + DRM_ERROR("ring init context: %d\n", + ret); + i915_gem_request_cancel(req); + goto validate_error; + } + i915_add_request_no_flush(req); + } + + ctx->rcs_initialized = true; + } } return ctx; + +validate_error: + intel_destroy_ringbuffer_obj(ctx->engine[ring->id].ringbuf); + drm_gem_object_unreference(&ctx->engine[ring->id].state->base); + ctx->engine[ring->id].ringbuf = NULL; + ctx->engine[ring->id].state = NULL; + return ERR_PTR(ret); } void diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 770a6f6..19ad961 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1350,6 +1350,9 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; + lrc_setup_hardware_status_page(ring, + ring->default_context->engine[ring->id].state); + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); @@ -1739,8 +1742,33 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin if (ret) return ret; - ret = intel_lr_context_deferred_create(ring->default_context, ring); + ret = intel_lr_context_deferred_alloc(ring->default_context, ring); + if (ret) + return ret; + + ret = i915_gem_obj_ggtt_pin( + ring->default_context->engine[ring->id].state, + GEN8_LR_CONTEXT_ALIGN, 0); + if (ret) { + DRM_DEBUG_DRIVER("Pin LRC backing obj failed: %d\n", + ret); + return ret; + } + + ret = intel_pin_and_map_ringbuffer_obj(dev, + ring->default_context->engine[ring->id].ringbuf); + if (ret) { + DRM_ERROR( + "Failed to pin and map ringbuffer %s: %d\n", + ring->name, ret); + goto error_unpin_ggtt; + } + + return ret; +error_unpin_ggtt: + i915_gem_object_ggtt_unpin( + ring->default_context->engine[ring->id].state); return ret; } @@ -1942,14 +1970,8 @@ int intel_logical_rings_init(struct drm_device *dev) goto cleanup_vebox_ring; } - ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); - if (ret) - goto cleanup_bsd2_ring; - return 0; -cleanup_bsd2_ring: - intel_logical_ring_cleanup(&dev_priv->ring[VCS2]); cleanup_vebox_ring: intel_logical_ring_cleanup(&dev_priv->ring[VECS]); cleanup_blt_ring: @@ -2146,7 +2168,7 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) return ret; } -static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, +void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, struct drm_i915_gem_object *default_ctx_obj) { struct drm_i915_private *dev_priv = ring->dev->dev_private; @@ -2164,7 +2186,7 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, } /** - * intel_lr_context_deferred_create() - create the LRC specific bits of a context + * intel_lr_context_deferred_alloc() - create the LRC specific bits of a context * @ctx: LR context to create. * @ring: engine to be used with the context. * @@ -2176,10 +2198,10 @@ static void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, * * Return: non-zero on error. */ -int intel_lr_context_deferred_create(struct intel_context *ctx, + +int intel_lr_context_deferred_alloc(struct intel_context *ctx, struct intel_engine_cs *ring) { - const bool is_global_default_ctx = (ctx == ring->default_context); struct drm_device *dev = ring->dev; struct drm_i915_gem_object *ctx_obj; uint32_t context_size; @@ -2197,22 +2219,12 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return -ENOMEM; } - if (is_global_default_ctx) { - ret = i915_gem_obj_ggtt_pin(ctx_obj, GEN8_LR_CONTEXT_ALIGN, 0); - if (ret) { - DRM_DEBUG_DRIVER("Pin LRC backing obj failed: %d\n", - ret); - drm_gem_object_unreference(&ctx_obj->base); - return ret; - } - } - ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL); if (!ringbuf) { DRM_DEBUG_DRIVER("Failed to allocate ringbuffer %s\n", ring->name); ret = -ENOMEM; - goto error_unpin_ctx; + goto error_deref_obj; } ringbuf->ring = ring; @@ -2232,65 +2244,24 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, ring->name, ret); goto error_free_rbuf; } - - if (is_global_default_ctx) { - ret = intel_pin_and_map_ringbuffer_obj(dev, ringbuf); - if (ret) { - DRM_ERROR( - "Failed to pin and map ringbuffer %s: %d\n", - ring->name, ret); - goto error_destroy_rbuf; - } - } - } ret = populate_lr_context(ctx, ctx_obj, ring, ringbuf); if (ret) { DRM_DEBUG_DRIVER("Failed to populate LRC: %d\n", ret); - goto error; + goto error_destroy_rbuf; } ctx->engine[ring->id].ringbuf = ringbuf; ctx->engine[ring->id].state = ctx_obj; - if (ctx == ring->default_context) - lrc_setup_hardware_status_page(ring, ctx_obj); - else if (ring->id == RCS && !ctx->rcs_initialized) { - if (ring->init_context) { - struct drm_i915_gem_request *req; - - ret = i915_gem_request_alloc(ring, ctx, &req); - if (ret) - return ret; - - ret = ring->init_context(req); - if (ret) { - DRM_ERROR("ring init context: %d\n", ret); - i915_gem_request_cancel(req); - ctx->engine[ring->id].ringbuf = NULL; - ctx->engine[ring->id].state = NULL; - goto error; - } - - i915_add_request_no_flush(req); - } - - ctx->rcs_initialized = true; - } - return 0; -error: - if (is_global_default_ctx) - intel_unpin_ringbuffer_obj(ringbuf); error_destroy_rbuf: intel_destroy_ringbuffer_obj(ringbuf); error_free_rbuf: kfree(ringbuf); -error_unpin_ctx: - if (is_global_default_ctx) - i915_gem_object_ggtt_unpin(ctx_obj); +error_deref_obj: drm_gem_object_unreference(&ctx_obj->base); return ret; } diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 9d2e98a..2cec0ee 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -67,8 +67,8 @@ static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf, /* Logical Ring Contexts */ void intel_lr_context_free(struct intel_context *ctx); -int intel_lr_context_deferred_create(struct intel_context *ctx, - struct intel_engine_cs *ring); +int intel_lr_context_deferred_alloc(struct intel_context *ctx, + struct intel_engine_cs *ring); void intel_lr_context_unpin(struct intel_engine_cs *ring, struct intel_context *ctx); void intel_lr_context_reset(struct drm_device *dev, @@ -84,5 +84,7 @@ u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj); bool intel_lrc_irq_handler(struct intel_engine_cs *ring); void intel_execlists_retire_requests(struct intel_engine_cs *ring); +void lrc_setup_hardware_status_page(struct intel_engine_cs *ring, + struct drm_i915_gem_object *default_ctx_obj); #endif /* _INTEL_LRC_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e39c891..b5e5d45 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2664,6 +2664,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->dispatch_execbuffer = i830_dispatch_execbuffer; else ring->dispatch_execbuffer = i915_dispatch_execbuffer; + ring->switch_context = i915_switch_context; ring->init_hw = init_render_ring; ring->cleanup = render_ring_cleanup; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 73b0bd8..ba3049b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -177,6 +177,7 @@ struct intel_engine_cs { int (*init_hw)(struct intel_engine_cs *ring); int (*init_context)(struct drm_i915_gem_request *req); + int (*switch_context)(struct drm_i915_gem_request *req); void (*write_tail)(struct intel_engine_cs *ring, u32 value); -- 2.1.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx