aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2013-04-25 22:29:27 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-05-02 10:09:47 -0400
commit409851f48939dffdd9f19a43830f54eac2c19a53 (patch)
tree6ec5a11ba6d6cec8959716a6aba99a392fe222e1 /drivers/gpu
parent62d1f92e06aef9665d71ca7e986b3047ecf0b3c7 (diff)
radeon: add bo tracking debugfs
This is to allow debugging of userspace program not freeing buffer after, which is basicly a memory leak. This print the list of all gem object along with their size and placement (VRAM,GTT,CPU) and with the pid of the task that created them. agd5f: add warning fix Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h5
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c50
3 files changed, 59 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index d6c8cbaa8693..3ef7543a2986 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -358,7 +358,8 @@ struct radeon_bo {
358 struct radeon_device *rdev; 358 struct radeon_device *rdev;
359 struct drm_gem_object gem_base; 359 struct drm_gem_object gem_base;
360 360
361 struct ttm_bo_kmap_obj dma_buf_vmap; 361 struct ttm_bo_kmap_obj dma_buf_vmap;
362 pid_t pid;
362}; 363};
363#define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base) 364#define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base)
364 365
@@ -372,6 +373,8 @@ struct radeon_bo_list {
372 u32 tiling_flags; 373 u32 tiling_flags;
373}; 374};
374 375
376int radeon_gem_debugfs_init(struct radeon_device *rdev);
377
375/* sub-allocation manager, it has to be protected by another lock. 378/* sub-allocation manager, it has to be protected by another lock.
376 * By conception this is an helper for other part of the driver 379 * By conception this is an helper for other part of the driver
377 * like the indirect buffer or semaphore, which both have their 380 * like the indirect buffer or semaphore, which both have their
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 237b7a7549e6..a8f608903989 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1178,6 +1178,11 @@ int radeon_device_init(struct radeon_device *rdev,
1178 if (r) 1178 if (r)
1179 DRM_ERROR("ib ring test failed (%d).\n", r); 1179 DRM_ERROR("ib ring test failed (%d).\n", r);
1180 1180
1181 r = radeon_gem_debugfs_init(rdev);
1182 if (r) {
1183 DRM_ERROR("registering gem debugfs failed (%d).\n", r);
1184 }
1185
1181 if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { 1186 if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
1182 /* Acceleration not working on AGP card try again 1187 /* Acceleration not working on AGP card try again
1183 * with fallback to PCI or PCIE GART 1188 * with fallback to PCI or PCIE GART
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index fe5c1f6b7957..aa796031ab65 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -84,6 +84,7 @@ retry:
84 return r; 84 return r;
85 } 85 }
86 *obj = &robj->gem_base; 86 *obj = &robj->gem_base;
87 robj->pid = task_pid_nr(current);
87 88
88 mutex_lock(&rdev->gem.mutex); 89 mutex_lock(&rdev->gem.mutex);
89 list_add_tail(&robj->list, &rdev->gem.objects); 90 list_add_tail(&robj->list, &rdev->gem.objects);
@@ -575,3 +576,52 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
575{ 576{
576 return drm_gem_handle_delete(file_priv, handle); 577 return drm_gem_handle_delete(file_priv, handle);
577} 578}
579
580#if defined(CONFIG_DEBUG_FS)
581static int radeon_debugfs_gem_info(struct seq_file *m, void *data)
582{
583 struct drm_info_node *node = (struct drm_info_node *)m->private;
584 struct drm_device *dev = node->minor->dev;
585 struct radeon_device *rdev = dev->dev_private;
586 struct radeon_bo *rbo;
587 unsigned i = 0;
588
589 mutex_lock(&rdev->gem.mutex);
590 list_for_each_entry(rbo, &rdev->gem.objects, list) {
591 unsigned domain;
592 const char *placement;
593
594 domain = radeon_mem_type_to_domain(rbo->tbo.mem.mem_type);
595 switch (domain) {
596 case RADEON_GEM_DOMAIN_VRAM:
597 placement = "VRAM";
598 break;
599 case RADEON_GEM_DOMAIN_GTT:
600 placement = " GTT";
601 break;
602 case RADEON_GEM_DOMAIN_CPU:
603 default:
604 placement = " CPU";
605 break;
606 }
607 seq_printf(m, "bo[0x%08x] %8ldkB %8ldMB %s pid %8ld\n",
608 i, radeon_bo_size(rbo) >> 10, radeon_bo_size(rbo) >> 20,
609 placement, (unsigned long)rbo->pid);
610 i++;
611 }
612 mutex_unlock(&rdev->gem.mutex);
613 return 0;
614}
615
616static struct drm_info_list radeon_debugfs_gem_list[] = {
617 {"radeon_gem_info", &radeon_debugfs_gem_info, 0, NULL},
618};
619#endif
620
621int radeon_gem_debugfs_init(struct radeon_device *rdev)
622{
623#if defined(CONFIG_DEBUG_FS)
624 return radeon_debugfs_add_files(rdev, radeon_debugfs_gem_list, 1);
625#endif
626 return 0;
627}