Commit 5ace5e96 authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter

drm/i915: Make lrc_init_wa_ctx compatible with ww locking, v3.

Make creation separate from pinning, in order to take the lock only
once, and pin the mapping with the lock held.

Changes since v1:
- Rebase on top of upstream changes.
Changes since v2:
- Fully clear wa_ctx on error.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarThomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20210323155059.628690-27-maarten.lankhorst@linux.intel.com
parent 7d1c2618
...@@ -1417,7 +1417,7 @@ gen10_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) ...@@ -1417,7 +1417,7 @@ gen10_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch)
#define CTX_WA_BB_SIZE (PAGE_SIZE) #define CTX_WA_BB_SIZE (PAGE_SIZE)
static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) static int lrc_create_wa_ctx(struct intel_engine_cs *engine)
{ {
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
struct i915_vma *vma; struct i915_vma *vma;
...@@ -1433,10 +1433,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) ...@@ -1433,10 +1433,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine)
goto err; goto err;
} }
err = i915_ggtt_pin(vma, NULL, 0, PIN_HIGH);
if (err)
goto err;
engine->wa_ctx.vma = vma; engine->wa_ctx.vma = vma;
return 0; return 0;
...@@ -1448,9 +1444,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine) ...@@ -1448,9 +1444,6 @@ static int lrc_setup_wa_ctx(struct intel_engine_cs *engine)
void lrc_fini_wa_ctx(struct intel_engine_cs *engine) void lrc_fini_wa_ctx(struct intel_engine_cs *engine)
{ {
i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
/* Called on error unwind, clear all flags to prevent further use */
memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx));
} }
typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);
...@@ -1462,6 +1455,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) ...@@ -1462,6 +1455,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine)
&wa_ctx->indirect_ctx, &wa_ctx->per_ctx &wa_ctx->indirect_ctx, &wa_ctx->per_ctx
}; };
wa_bb_func_t wa_bb_fn[ARRAY_SIZE(wa_bb)]; wa_bb_func_t wa_bb_fn[ARRAY_SIZE(wa_bb)];
struct i915_gem_ww_ctx ww;
void *batch, *batch_ptr; void *batch, *batch_ptr;
unsigned int i; unsigned int i;
int err; int err;
...@@ -1490,7 +1484,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) ...@@ -1490,7 +1484,7 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine)
return; return;
} }
err = lrc_setup_wa_ctx(engine); err = lrc_create_wa_ctx(engine);
if (err) { if (err) {
/* /*
* We continue even if we fail to initialize WA batch * We continue even if we fail to initialize WA batch
...@@ -1503,7 +1497,22 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) ...@@ -1503,7 +1497,22 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine)
return; return;
} }
if (!engine->wa_ctx.vma)
return;
i915_gem_ww_ctx_init(&ww, true);
retry:
err = i915_gem_object_lock(wa_ctx->vma->obj, &ww);
if (!err)
err = i915_ggtt_pin(wa_ctx->vma, &ww, 0, PIN_HIGH);
if (err)
goto err;
batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB); batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB);
if (IS_ERR(batch)) {
err = PTR_ERR(batch);
goto err_unpin;
}
/* /*
* Emit the two workaround batch buffers, recording the offset from the * Emit the two workaround batch buffers, recording the offset from the
...@@ -1528,8 +1537,26 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine) ...@@ -1528,8 +1537,26 @@ void lrc_init_wa_ctx(struct intel_engine_cs *engine)
__i915_gem_object_release_map(wa_ctx->vma->obj); __i915_gem_object_release_map(wa_ctx->vma->obj);
/* Verify that we can handle failure to setup the wa_ctx */ /* Verify that we can handle failure to setup the wa_ctx */
if (err || i915_inject_probe_error(engine->i915, -ENODEV)) if (!err)
lrc_fini_wa_ctx(engine); err = i915_inject_probe_error(engine->i915, -ENODEV);
err_unpin:
if (err)
i915_vma_unpin(wa_ctx->vma);
err:
if (err == -EDEADLK) {
err = i915_gem_ww_ctx_backoff(&ww);
if (!err)
goto retry;
}
i915_gem_ww_ctx_fini(&ww);
if (err) {
i915_vma_put(engine->wa_ctx.vma);
/* Clear all flags to prevent further use */
memset(wa_ctx, 0, sizeof(*wa_ctx));
}
} }
static void st_update_runtime_underflow(struct intel_context *ce, s32 dt) static void st_update_runtime_underflow(struct intel_context *ce, s32 dt)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment