This allows to hopefully find out who was responsible for the GPU death. To simplify post-portem analysis, we also search for the the processes names when gathering the i915_error_state and when peeking at the list of active gem objects in debugfs. Signed-off-by: Eugeni Dodonov <eugeni.dodonov at intel.com> --- drivers/gpu/drm/i915/i915_debugfs.c | 18 ++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ drivers/gpu/drm/i915/i915_irq.c | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index a017b98..f61a7cf 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -151,6 +151,20 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) } if (obj->ring != NULL) seq_printf(m, " (%s)", obj->ring->name); + if (obj->pid) { + struct pid *p; + struct task_struct *tsk = NULL; + p = find_get_pid(obj->pid); + if (p) + tsk = get_pid_task(p, PIDTYPE_PID); + + seq_printf(m, " (pid: %5d [%s])", + obj->pid, + (tsk) ? tsk->comm : "unknown"); + + put_pid(p); + + } } static int i915_gem_object_list_info(struct seq_file *m, void *data) @@ -730,6 +744,10 @@ static void print_error_buffers(struct seq_file *m, seq_printf(m, " (name: %d)", err->name); if (err->fence_reg != I915_FENCE_REG_NONE) seq_printf(m, " (fence: %d)", err->fence_reg); + if (err->pid) { + seq_printf(m, " (pid: %d [%s])", err->pid, + (err->comm) ? err->comm : "unknown"); + } seq_printf(m, "\n"); err++; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9689ca3..cb9bfab 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -193,6 +193,8 @@ struct drm_i915_error_state { u32 purgeable:1; u32 ring:4; u32 cache_level:2; + u32 pid; + char comm[TASK_COMM_LEN]; } *active_bo, *pinned_bo; u32 active_bo_count, pinned_bo_count; struct intel_overlay_error_state *overlay; @@ -891,6 +893,9 @@ struct drm_i915_gem_object { /** for phy allocated objects */ struct drm_i915_gem_phys_object *phys_obj; + /** pid of caller process */ + uint32_t pid; + /** * Number of crtcs where this object is currently the fb, but * will be page flipped away on the next vblank. When it diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 65e1f00..b88bb97 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1140,6 +1140,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, list_add_tail(&obj->exec_list, &objects); obj->exec_handle = exec[i].handle; obj->exec_entry = &exec[i]; + + /* Discover pid of caller process */ + obj->pid = file->pid; eb_add_object(eb, obj); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5bd4361..e377966 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -789,8 +789,22 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, int i = 0; list_for_each_entry(obj, head, mm_list) { + struct pid *p; + struct task_struct *tsk = NULL; + err->size = obj->base.size; err->name = obj->base.name; + + err->pid = obj->pid; + p = find_get_pid(err->pid); + if (p) + tsk = get_pid_task(p, PIDTYPE_PID); + + snprintf(err->comm, TASK_COMM_LEN, + (tsk) ? tsk->comm : "unknown"); + + put_pid(p); + err->seqno = obj->last_rendering_seqno; err->gtt_offset = obj->gtt_offset; err->read_domains = obj->base.read_domains; -- 1.7.8.1