diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-04-15 10:39:02 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-04-15 12:39:57 +0100 |
commit | b0fd47adc6233e4c198a97e1ddb05accd31eeacb (patch) | |
tree | f99e371e5d15c0ab0783a2a0bc7467f5f7a8c4b7 /drivers/gpu/drm/i915/i915_gpu_error.c | |
parent | drm/i915: set "ret" correctly on error paths (diff) | |
download | linux-dev-b0fd47adc6233e4c198a97e1ddb05accd31eeacb.tar.xz linux-dev-b0fd47adc6233e4c198a97e1ddb05accd31eeacb.zip |
drm/i915: Copy user requested buffers into the error state
Introduce a new execobject.flag (EXEC_OBJECT_CAPTURE) that userspace may
use to indicate that it wants the contents of this buffer preserved in
the error state (/sys/class/drm/cardN/error) following a GPU hang
involving this batch.
Use this at your discretion, the contents of the error state. although
compressed, are allocated with GFP_ATOMIC (i.e. limited) and kept for all
eternity (until the error state is destroyed).
Based on an earlier patch by Ben Widawsky <ben@bwidawsk.net>
Testcase: igt/gem_exec_capture
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Matt Turner <mattst88@gmail.com>
Acked-by: Ben Widawsky <ben@bwidawsk.net>
Acked-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170415093902.22581-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gpu_error.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gpu_error.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 8effc59f5cb5..4b247b050dcd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -712,6 +712,10 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, print_error_obj(m, dev_priv->engine[i], NULL, obj); } + for (j = 0; j < ee->user_bo_count; j++) + print_error_obj(m, dev_priv->engine[i], + "user", ee->user_bo[j]); + if (ee->num_requests) { err_printf(m, "%s --- %d requests\n", dev_priv->engine[i]->name, @@ -825,11 +829,15 @@ void __i915_gpu_state_free(struct kref *error_ref) { struct i915_gpu_state *error = container_of(error_ref, typeof(*error), ref); - int i; + long i, j; for (i = 0; i < ARRAY_SIZE(error->engine); i++) { struct drm_i915_error_engine *ee = &error->engine[i]; + for (j = 0; j < ee->user_bo_count; j++) + i915_error_object_free(ee->user_bo[j]); + kfree(ee->user_bo); + i915_error_object_free(ee->batchbuffer); i915_error_object_free(ee->wa_batchbuffer); i915_error_object_free(ee->ringbuffer); @@ -1346,6 +1354,35 @@ static void record_context(struct drm_i915_error_context *e, e->active = ctx->active_count; } +static void request_record_user_bo(struct drm_i915_gem_request *request, + struct drm_i915_error_engine *ee) +{ + struct i915_gem_capture_list *c; + struct drm_i915_error_object **bo; + long count; + + count = 0; + for (c = request->capture_list; c; c = c->next) + count++; + + bo = NULL; + if (count) + bo = kcalloc(count, sizeof(*bo), GFP_ATOMIC); + if (!bo) + return; + + count = 0; + for (c = request->capture_list; c; c = c->next) { + bo[count] = i915_error_object_create(request->i915, c->vma); + if (!bo[count]) + break; + count++; + } + + ee->user_bo = bo; + ee->user_bo_count = count; +} + static void i915_gem_record_rings(struct drm_i915_private *dev_priv, struct i915_gpu_state *error) { @@ -1392,6 +1429,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, ee->wa_batchbuffer = i915_error_object_create(dev_priv, engine->scratch); + request_record_user_bo(request, ee); ee->ctx = i915_error_object_create(dev_priv, |