From: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com
Make creation separate from pinning, in order to take the lock only once, and pin the mapping with the lock held.
Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com --- .../drm/i915/gt/intel_engine_workaround_bb.c | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c b/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c index b03bdfc92bb2..f3636b73cc10 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_workaround_bb.c @@ -229,7 +229,7 @@ gen10_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
#define CTX_WA_BB_OBJ_SIZE (PAGE_SIZE)
-static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) +static int lrc_init_wa_ctx(struct intel_engine_cs *engine) { struct drm_i915_gem_object *obj; struct i915_vma *vma; @@ -245,10 +245,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) goto err; }
- err = i915_ggtt_pin(vma, NULL, 0, PIN_HIGH); - if (err) - goto err; - engine->wa_ctx.vma = vma; return 0;
@@ -257,6 +253,18 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) return err; }
+static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine, bool unpin) +{ + if (!engine->wa_ctx.vma) + return; + + if (unpin) + i915_vma_unpin(engine->wa_ctx.vma); + + i915_vma_put(engine->wa_ctx.vma); + engine->wa_ctx.vma = NULL; +} + typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);
int intel_init_workaround_bb(struct intel_engine_cs *engine) @@ -266,6 +274,7 @@ int intel_init_workaround_bb(struct intel_engine_cs *engine) &wa_ctx->per_ctx }; wa_bb_func_t wa_bb_fn[2]; void *batch, *batch_ptr; + struct i915_gem_ww_ctx ww; unsigned int i; int ret;
@@ -293,13 +302,21 @@ int intel_init_workaround_bb(struct intel_engine_cs *engine) return 0; }
- ret = lrc_setup_wa_ctx(engine); + ret = lrc_init_wa_ctx(engine); if (ret) { drm_dbg(&engine->i915->drm, "Failed to setup context WA page: %d\n", ret); return ret; }
+ i915_gem_ww_ctx_init(&ww, true); +retry: + ret = i915_gem_object_lock(wa_ctx->vma->obj, &ww); + if (!ret) + ret = i915_ggtt_pin(wa_ctx->vma, &ww, 0, PIN_HIGH); + if (ret) + goto err; + batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB);
/* @@ -323,13 +340,25 @@ int intel_init_workaround_bb(struct intel_engine_cs *engine)
__i915_gem_object_flush_map(wa_ctx->vma->obj, 0, batch_ptr - batch); __i915_gem_object_release_map(wa_ctx->vma->obj); + + if (ret) + i915_vma_unpin(wa_ctx->vma); + +err: + if (ret == -EDEADLK) { + ret = i915_gem_ww_ctx_backoff(&ww); + if (!ret) + goto retry; + } + i915_gem_ww_ctx_fini(&ww); if (ret) - intel_fini_workaround_bb(engine); + lrc_destroy_wa_ctx(engine, false);
return ret; }
+ void intel_fini_workaround_bb(struct intel_engine_cs *engine) { - i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); + lrc_destroy_wa_ctx(engine, true); }