Commit 01c1b2cb authored by Chris Wilson's avatar Chris Wilson Committed by Jani Nikula

drm/i915/gem: Take local vma references for the parser

Take and hold a reference to each of the vma (and their objects) as we
process them with the cmdparser. This stops them being freed during the
work if the GEM execbuf is interrupted and the request we expected to
keep the objects alive is incomplete.

Fixes: 686c7c35 ("drm/i915/gem: Asynchronous cmdparser")
Closes: https://gitlab.freedesktop.org/drm/intel/issues/970Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200113154555.1909639-1-chris@chris-wilson.co.uk
(cherry picked from commit 36c8e356)
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 88a9c66d
...@@ -1981,9 +1981,20 @@ static int __eb_parse(struct dma_fence_work *work) ...@@ -1981,9 +1981,20 @@ static int __eb_parse(struct dma_fence_work *work)
pw->trampoline); pw->trampoline);
} }
static void __eb_parse_release(struct dma_fence_work *work)
{
struct eb_parse_work *pw = container_of(work, typeof(*pw), base);
if (pw->trampoline)
i915_active_release(&pw->trampoline->active);
i915_active_release(&pw->shadow->active);
i915_active_release(&pw->batch->active);
}
static const struct dma_fence_work_ops eb_parse_ops = { static const struct dma_fence_work_ops eb_parse_ops = {
.name = "eb_parse", .name = "eb_parse",
.work = __eb_parse, .work = __eb_parse,
.release = __eb_parse_release,
}; };
static int eb_parse_pipeline(struct i915_execbuffer *eb, static int eb_parse_pipeline(struct i915_execbuffer *eb,
...@@ -1997,6 +2008,20 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, ...@@ -1997,6 +2008,20 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
if (!pw) if (!pw)
return -ENOMEM; return -ENOMEM;
err = i915_active_acquire(&eb->batch->active);
if (err)
goto err_free;
err = i915_active_acquire(&shadow->active);
if (err)
goto err_batch;
if (trampoline) {
err = i915_active_acquire(&trampoline->active);
if (err)
goto err_shadow;
}
dma_fence_work_init(&pw->base, &eb_parse_ops); dma_fence_work_init(&pw->base, &eb_parse_ops);
pw->engine = eb->engine; pw->engine = eb->engine;
...@@ -2006,7 +2031,9 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, ...@@ -2006,7 +2031,9 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
pw->shadow = shadow; pw->shadow = shadow;
pw->trampoline = trampoline; pw->trampoline = trampoline;
dma_resv_lock(pw->batch->resv, NULL); err = dma_resv_lock_interruptible(pw->batch->resv, NULL);
if (err)
goto err_trampoline;
err = dma_resv_reserve_shared(pw->batch->resv, 1); err = dma_resv_reserve_shared(pw->batch->resv, 1);
if (err) if (err)
...@@ -2034,6 +2061,14 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb, ...@@ -2034,6 +2061,14 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
err_batch_unlock: err_batch_unlock:
dma_resv_unlock(pw->batch->resv); dma_resv_unlock(pw->batch->resv);
err_trampoline:
if (trampoline)
i915_active_release(&trampoline->active);
err_shadow:
i915_active_release(&shadow->active);
err_batch:
i915_active_release(&eb->batch->active);
err_free:
kfree(pw); kfree(pw);
return err; return err;
} }
......
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