[PATCH 1/1] drm/i915: track pid of GEM object creators

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux