In order to handle asynchronous error conditions, we need to store the error status on the fence itself, and inspect it upon signaling. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Mika Kuoppala <mika.kuoppala@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_sw_fence.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/i915/i915_sw_fence.h | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index a277f8eb7beb..49043687effc 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -179,7 +179,7 @@ static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence, do { list_for_each_entry_safe(pos, next, &x->task_list, task_list) - pos->func(pos, TASK_NORMAL, 0, &extra); + pos->func(pos, TASK_NORMAL, fence->error, &extra); if (list_empty(&extra)) break; @@ -240,6 +240,7 @@ void __i915_sw_fence_init(struct i915_sw_fence *fence, kref_init(&fence->kref); atomic_set(&fence->pending, 1); fence->flags = (unsigned long)fn; + fence->error = 0; } static void __i915_sw_fence_commit(struct i915_sw_fence *fence) @@ -254,13 +255,21 @@ void i915_sw_fence_commit(struct i915_sw_fence *fence) __i915_sw_fence_commit(fence); } -static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int flags, void *key) +static int i915_sw_fence_wake(wait_queue_t *wq, unsigned mode, int err, void *key) { + struct i915_sw_fence *fence = wq->private; + list_del(&wq->task_list); - __i915_sw_fence_complete(wq->private, key); - i915_sw_fence_put(wq->private); + + if (err && !fence->error) + fence->error = err; + + __i915_sw_fence_complete(fence, key); + i915_sw_fence_put(fence); + if (wq->flags & I915_SW_FENCE_FLAG_ALLOC) kfree(wq); + return 0; } @@ -402,6 +411,9 @@ static void timer_i915_sw_fence_wake(unsigned long data) dma_fence_put(cb->dma); cb->dma = NULL; + if (!cb->fence->error) + cb->fence->error = -ETIMEDOUT; + __i915_sw_fence_commit(cb->fence); cb->timer.function = NULL; } @@ -412,8 +424,11 @@ static void dma_i915_sw_fence_wake(struct dma_fence *dma, struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base); del_timer_sync(&cb->timer); - if (cb->timer.function) + if (cb->timer.function) { + if (dma->error && !cb->fence->error) + cb->fence->error = dma->error; __i915_sw_fence_commit(cb->fence); + } dma_fence_put(cb->dma); kfree(cb); diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h b/drivers/gpu/drm/i915/i915_sw_fence.h index d31cefbbcc04..b543ef2ad225 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.h +++ b/drivers/gpu/drm/i915/i915_sw_fence.h @@ -25,6 +25,7 @@ struct i915_sw_fence { unsigned long flags; struct kref kref; atomic_t pending; + int error; }; #define I915_SW_FENCE_CHECKED_BIT 0 /* used internally for DAG checking */ -- 2.11.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx