Commit 19eb9189 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Don't wait for a spinlock inside error capture

If we can't grab the breadcrumb's spinlock, possibly due to a driver
deadlock inside the waiters, ignore them. Like hangcheck, error
capturing must work no matter how the driver/GPU dies.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20160906073844.22561-1-chris@chris-wilson.co.ukReviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent fc32de93
...@@ -489,7 +489,10 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, ...@@ -489,7 +489,10 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
} }
} }
if (ee->num_waiters) { if (IS_ERR(ee->waiters)) {
err_printf(m, "%s --- ? waiters [unable to acquire spinlock]\n",
dev_priv->engine[i].name);
} else if (ee->num_waiters) {
err_printf(m, "%s --- %d waiters\n", err_printf(m, "%s --- %d waiters\n",
dev_priv->engine[i].name, dev_priv->engine[i].name,
ee->num_waiters); ee->num_waiters);
...@@ -648,7 +651,8 @@ static void i915_error_state_free(struct kref *error_ref) ...@@ -648,7 +651,8 @@ static void i915_error_state_free(struct kref *error_ref)
i915_error_object_free(ee->wa_ctx); i915_error_object_free(ee->wa_ctx);
kfree(ee->requests); kfree(ee->requests);
kfree(ee->waiters); if (!IS_ERR_OR_NULL(ee->waiters))
kfree(ee->waiters);
} }
i915_error_object_free(error->semaphore); i915_error_object_free(error->semaphore);
...@@ -933,7 +937,14 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, ...@@ -933,7 +937,14 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine,
ee->num_waiters = 0; ee->num_waiters = 0;
ee->waiters = NULL; ee->waiters = NULL;
spin_lock(&b->lock); if (RB_EMPTY_ROOT(&b->waiters))
return;
if (!spin_trylock(&b->lock)) {
ee->waiters = ERR_PTR(-EDEADLK);
return;
}
count = 0; count = 0;
for (rb = rb_first(&b->waiters); rb != NULL; rb = rb_next(rb)) for (rb = rb_first(&b->waiters); rb != NULL; rb = rb_next(rb))
count++; count++;
...@@ -947,9 +958,13 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine, ...@@ -947,9 +958,13 @@ static void error_record_engine_waiters(struct intel_engine_cs *engine,
if (!waiter) if (!waiter)
return; return;
ee->waiters = waiter; if (!spin_trylock(&b->lock)) {
kfree(waiter);
ee->waiters = ERR_PTR(-EDEADLK);
return;
}
spin_lock(&b->lock); ee->waiters = waiter;
for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) { for (rb = rb_first(&b->waiters); rb; rb = rb_next(rb)) {
struct intel_wait *w = container_of(rb, typeof(*w), node); struct intel_wait *w = container_of(rb, typeof(*w), node);
......
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