[Intel-gfx] [PATCH 2/4] drm/i915: Track the error through the sw-fence
Chris Wilson
chris at chris-wilson.co.uk
Wed Mar 8 11:40:08 UTC 2017
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 at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Mika Kuoppala <mika.kuoppala at intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
---
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
More information about the Intel-gfx
mailing list