[Intel-gfx] [PATCH] drm/i915: Track clients and print their object usage in debugfs

Chris Wilson chris at chris-wilson.co.uk
Tue Jun 4 15:26:19 CEST 2013


By stashing a pointer of who opened the device and keeping a list of
open fd, we can then walk each client and inspect how many objects they
have open. For example,

i915_gem_objects:
1102 objects, 613646336 bytes
663 [662] objects, 468783104 [468750336] bytes in gtt
  37 [37] active objects, 46874624 [46874624] bytes
  626 [625] inactive objects, 421908480 [421875712] bytes
282 unbound objects, 6512640 bytes
85 purgeable objects, 6787072 bytes
28 pinned mappable objects, 3686400 bytes
40 fault mappable objects, 27783168 bytes
2145386496 [536870912] gtt total

Xorg: 43 objects, 32243712 bytes (10223616 active, 16683008 inactive, 4096 unbound)
gnome-shell: 30 objects, 28381184 bytes (0 active, 28336128 inactive, 0 unbound)
xonotic-linux64: 1032 objects, 569933824 bytes (46874624 active, 383545344 inactive, 6508544 unbound)

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_debugfs.c |   41 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_dma.c     |   18 ++++++++++++---
 drivers/gpu/drm/i915/i915_drv.h     |    5 ++++-
 drivers/gpu/drm/i915/i915_gem.c     |    1 +
 4 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 0e7e3c0..6c95e17 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -196,6 +196,32 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
 	} \
 } while (0)
 
+struct file_stats {
+	int count;
+	size_t total, active, inactive, unbound;
+};
+
+static int per_file_stats(int id, void *ptr, void *data)
+{
+	struct drm_i915_gem_object *obj = ptr;
+	struct file_stats *stats = data;
+
+	stats->count++;
+	stats->total += obj->base.size;
+
+	if (obj->gtt_space) {
+		if (!list_empty(&obj->ring_list))
+			stats->active += obj->base.size;
+		else
+			stats->inactive += obj->base.size;
+	} else {
+		if (!list_empty(&obj->global_list))
+			stats->unbound += obj->base.size;
+	}
+
+	return 0;
+}
+
 static int i915_gem_object_info(struct seq_file *m, void* data)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -204,6 +230,7 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
 	u32 count, mappable_count, purgeable_count;
 	size_t size, mappable_size, purgeable_size;
 	struct drm_i915_gem_object *obj;
+	struct drm_i915_file_private *file;
 	int ret;
 
 	ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -263,6 +290,20 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
 		   dev_priv->gtt.total,
 		   dev_priv->gtt.mappable_end - dev_priv->gtt.start);
 
+	seq_printf(m, "\n");
+	list_for_each_entry(file, &dev_priv->clients, link) {
+		struct file_stats stats;
+		memset(&stats, 0, sizeof(stats));
+		idr_for_each(&file->base->object_idr, per_file_stats, &stats);
+		seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu unbound)\n",
+			   file->task->comm,
+			   stats.count,
+			   stats.total,
+			   stats.active,
+			   stats.inactive,
+			   stats.unbound);
+	}
+
 	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ad4c493..a2d511f 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1805,6 +1805,7 @@ int i915_driver_unload(struct drm_device *dev)
 
 int i915_driver_open(struct drm_device *dev, struct drm_file *file)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_file_private *file_priv;
 
 	DRM_DEBUG_DRIVER("\n");
@@ -1813,12 +1814,18 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file)
 		return -ENOMEM;
 
 	file->driver_priv = file_priv;
+	file_priv->base = file;
 
 	spin_lock_init(&file_priv->mm.lock);
 	INIT_LIST_HEAD(&file_priv->mm.request_list);
 
 	idr_init(&file_priv->context_idr);
 
+	file_priv->task = current;
+	mutex_lock(&dev->struct_mutex);
+	list_add_tail(&file_priv->link, &dev_priv->clients);
+	mutex_unlock(&dev->struct_mutex);
+
 	return 0;
 }
 
@@ -1855,10 +1862,15 @@ void i915_driver_lastclose(struct drm_device * dev)
 	i915_dma_cleanup(dev);
 }
 
-void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
+void i915_driver_preclose(struct drm_device * dev, struct drm_file *file)
 {
-	i915_gem_context_close(dev, file_priv);
-	i915_gem_release(dev, file_priv);
+	struct drm_i915_file_private *file_priv = file->driver_priv;
+
+	i915_gem_context_close(dev, file);
+	i915_gem_release(dev, file);
+	mutex_lock(&dev->struct_mutex);
+	list_del(&file_priv->link);
+	mutex_unlock(&dev->struct_mutex);
 }
 
 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bfe0c58..f63cdd8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1047,8 +1047,8 @@ typedef struct drm_i915_private {
 	enum modeset_restore modeset_restore;
 	struct mutex modeset_restore_lock;
 
+	struct list_head clients;
 	struct i915_gtt gtt;
-
 	struct i915_gem_mm mm;
 
 	/* Kernel Modesetting */
@@ -1332,6 +1332,9 @@ struct drm_i915_gem_request {
 };
 
 struct drm_i915_file_private {
+	struct drm_file *base;
+	struct task_struct *task;
+	struct list_head link;
 	struct {
 		spinlock_t lock;
 		struct list_head request_list;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 61956a1..2b33dff 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4226,6 +4226,7 @@ i915_gem_load(struct drm_device *dev)
 				  SLAB_HWCACHE_ALIGN,
 				  NULL);
 
+	INIT_LIST_HEAD(&dev_priv->clients);
 	INIT_LIST_HEAD(&dev_priv->mm.active_list);
 	INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
 	INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
-- 
1.7.10.4




More information about the Intel-gfx mailing list