aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_debugfs.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-06-04 18:49:08 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-06 04:45:37 -0400
commit2db8e9d6b255a4fd070df70fa58306bf64b41984 (patch)
treeaf13861865fcd7a11132aec845b40266df11a412 /drivers/gpu/drm/i915/i915_debugfs.c
parentef1b460d1bab7e5b04c34f88c3dfa042528e7c27 (diff)
drm/i915: Track clients and print their object usage in debugfs
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) v2: Use existing drm->filelist as pointed out by Ben. v3: Not even stashing the task_struct is required as Ben pointed out drm_file->pid. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 0e7e3c04d939..d4e78b64ca87 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)
196 } \ 196 } \
197} while (0) 197} while (0)
198 198
199struct file_stats {
200 int count;
201 size_t total, active, inactive, unbound;
202};
203
204static int per_file_stats(int id, void *ptr, void *data)
205{
206 struct drm_i915_gem_object *obj = ptr;
207 struct file_stats *stats = data;
208
209 stats->count++;
210 stats->total += obj->base.size;
211
212 if (obj->gtt_space) {
213 if (!list_empty(&obj->ring_list))
214 stats->active += obj->base.size;
215 else
216 stats->inactive += obj->base.size;
217 } else {
218 if (!list_empty(&obj->global_list))
219 stats->unbound += obj->base.size;
220 }
221
222 return 0;
223}
224
199static int i915_gem_object_info(struct seq_file *m, void* data) 225static int i915_gem_object_info(struct seq_file *m, void* data)
200{ 226{
201 struct drm_info_node *node = (struct drm_info_node *) m->private; 227 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)
204 u32 count, mappable_count, purgeable_count; 230 u32 count, mappable_count, purgeable_count;
205 size_t size, mappable_size, purgeable_size; 231 size_t size, mappable_size, purgeable_size;
206 struct drm_i915_gem_object *obj; 232 struct drm_i915_gem_object *obj;
233 struct drm_file *file;
207 int ret; 234 int ret;
208 235
209 ret = mutex_lock_interruptible(&dev->struct_mutex); 236 ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -263,6 +290,21 @@ static int i915_gem_object_info(struct seq_file *m, void* data)
263 dev_priv->gtt.total, 290 dev_priv->gtt.total,
264 dev_priv->gtt.mappable_end - dev_priv->gtt.start); 291 dev_priv->gtt.mappable_end - dev_priv->gtt.start);
265 292
293 seq_printf(m, "\n");
294 list_for_each_entry_reverse(file, &dev->filelist, lhead) {
295 struct file_stats stats;
296
297 memset(&stats, 0, sizeof(stats));
298 idr_for_each(&file->object_idr, per_file_stats, &stats);
299 seq_printf(m, "%s: %u objects, %zu bytes (%zu active, %zu inactive, %zu unbound)\n",
300 get_pid_task(file->pid, PIDTYPE_PID)->comm,
301 stats.count,
302 stats.total,
303 stats.active,
304 stats.inactive,
305 stats.unbound);
306 }
307
266 mutex_unlock(&dev->struct_mutex); 308 mutex_unlock(&dev->struct_mutex);
267 309
268 return 0; 310 return 0;