Skip to content

Commit 57a78ca

Browse files
committed
drm/i915/gem: Mark the buffer pool as active for the cmdparser
If the execbuf is interrupted after building the cmdparser pipeline, and before we commit to submitting the request to HW, we would attempt to clean up the cmdparser early. While we held active references to the vma being parsed and constructed, we did not hold an active reference for the buffer pool itself. The result was that an interrupted execbuf could still have run the cmdparser pipeline, but since the buffer pool was idle, its target vma could have been recycled. Note this problem only occurs if the cmdparser is running async due to pipelined waits on busy fences, and the execbuf is interrupted. Fixes: 686c7c3 ("drm/i915/gem: Asynchronous cmdparser") Fixes: 16e8745 ("drm/i915/gt: Move the batch buffer pool from the engine to the gt") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20200604103751.18816-1-chris@chris-wilson.co.uk
1 parent 84f9cbf commit 57a78ca

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,38 @@ static const struct dma_fence_work_ops eb_parse_ops = {
19871987
.release = __eb_parse_release,
19881988
};
19891989

1990+
static inline int
1991+
__parser_mark_active(struct i915_vma *vma,
1992+
struct intel_timeline *tl,
1993+
struct dma_fence *fence)
1994+
{
1995+
struct intel_gt_buffer_pool_node *node = vma->private;
1996+
1997+
return i915_active_ref(&node->active, tl, fence);
1998+
}
1999+
2000+
static int
2001+
parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl)
2002+
{
2003+
int err;
2004+
2005+
mutex_lock(&tl->mutex);
2006+
2007+
err = __parser_mark_active(pw->shadow, tl, &pw->base.dma);
2008+
if (err)
2009+
goto unlock;
2010+
2011+
if (pw->trampoline) {
2012+
err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma);
2013+
if (err)
2014+
goto unlock;
2015+
}
2016+
2017+
unlock:
2018+
mutex_unlock(&tl->mutex);
2019+
return err;
2020+
}
2021+
19902022
static int eb_parse_pipeline(struct i915_execbuffer *eb,
19912023
struct i915_vma *shadow,
19922024
struct i915_vma *trampoline)
@@ -2021,20 +2053,25 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
20212053
pw->shadow = shadow;
20222054
pw->trampoline = trampoline;
20232055

2056+
/* Mark active refs early for this worker, in case we get interrupted */
2057+
err = parser_mark_active(pw, eb->context->timeline);
2058+
if (err)
2059+
goto err_commit;
2060+
20242061
err = dma_resv_lock_interruptible(pw->batch->resv, NULL);
20252062
if (err)
2026-
goto err_trampoline;
2063+
goto err_commit;
20272064

20282065
err = dma_resv_reserve_shared(pw->batch->resv, 1);
20292066
if (err)
2030-
goto err_batch_unlock;
2067+
goto err_commit_unlock;
20312068

20322069
/* Wait for all writes (and relocs) into the batch to complete */
20332070
err = i915_sw_fence_await_reservation(&pw->base.chain,
20342071
pw->batch->resv, NULL, false,
20352072
0, I915_FENCE_GFP);
20362073
if (err < 0)
2037-
goto err_batch_unlock;
2074+
goto err_commit_unlock;
20382075

20392076
/* Keep the batch alive and unwritten as we parse */
20402077
dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma);
@@ -2049,11 +2086,13 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
20492086
dma_fence_work_commit_imm(&pw->base);
20502087
return 0;
20512088

2052-
err_batch_unlock:
2089+
err_commit_unlock:
20532090
dma_resv_unlock(pw->batch->resv);
2054-
err_trampoline:
2055-
if (trampoline)
2056-
i915_active_release(&trampoline->active);
2091+
err_commit:
2092+
i915_sw_fence_set_error_once(&pw->base.chain, err);
2093+
dma_fence_work_commit_imm(&pw->base);
2094+
return err;
2095+
20572096
err_shadow:
20582097
i915_active_release(&shadow->active);
20592098
err_batch:
@@ -2099,6 +2138,7 @@ static int eb_parse(struct i915_execbuffer *eb)
20992138
goto err;
21002139
}
21012140
i915_gem_object_set_readonly(shadow->obj);
2141+
shadow->private = pool;
21022142

21032143
trampoline = NULL;
21042144
if (CMDPARSER_USES_GGTT(eb->i915)) {
@@ -2112,6 +2152,7 @@ static int eb_parse(struct i915_execbuffer *eb)
21122152
shadow = trampoline;
21132153
goto err_shadow;
21142154
}
2155+
shadow->private = pool;
21152156

21162157
eb->batch_flags |= I915_DISPATCH_SECURE;
21172158
}
@@ -2128,7 +2169,6 @@ static int eb_parse(struct i915_execbuffer *eb)
21282169
eb->trampoline = trampoline;
21292170
eb->batch_start_offset = 0;
21302171

2131-
shadow->private = pool;
21322172
return 0;
21332173

21342174
err_trampoline:

0 commit comments

Comments
 (0)