diff mbox

radeon: add bo tracking debugfs

Message ID 1366943367-817-1-git-send-email-j.glisse@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jerome Glisse April 26, 2013, 2:29 a.m. UTC
From: Jerome Glisse <jglisse@redhat.com>

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.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
---
 drivers/gpu/drm/radeon/radeon.h        |  5 +++-
 drivers/gpu/drm/radeon/radeon_device.c |  5 ++++
 drivers/gpu/drm/radeon/radeon_gem.c    | 50 ++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 1 deletion(-)

Comments

Alex Deucher April 25, 2013, 10:41 p.m. UTC | #1
On Thu, Apr 25, 2013 at 10:29 PM,  <j.glisse@gmail.com> wrote:
> From: Jerome Glisse <jglisse@redhat.com>
>
> 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.
>
> Signed-off-by: Jerome Glisse <jglisse@redhat.com>

Looks good to me.  Unless there are any objections, I'll pull it in for 3.10

Alex

> ---
>  drivers/gpu/drm/radeon/radeon.h        |  5 +++-
>  drivers/gpu/drm/radeon/radeon_device.c |  5 ++++
>  drivers/gpu/drm/radeon/radeon_gem.c    | 50 ++++++++++++++++++++++++++++++++++
>  3 files changed, 59 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 18904fb..bd28ee6 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -358,7 +358,8 @@ struct radeon_bo {
>         struct radeon_device            *rdev;
>         struct drm_gem_object           gem_base;
>
> -       struct ttm_bo_kmap_obj dma_buf_vmap;
> +       struct ttm_bo_kmap_obj          dma_buf_vmap;
> +       pid_t                           pid;
>  };
>  #define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base)
>
> @@ -372,6 +373,8 @@ struct radeon_bo_list {
>         u32                     tiling_flags;
>  };
>
> +int radeon_gem_debugfs_init(struct radeon_device *rdev);
> +
>  /* sub-allocation manager, it has to be protected by another lock.
>   * By conception this is an helper for other part of the driver
>   * 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 62d0ba3..76166ae 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -1142,6 +1142,11 @@ int radeon_device_init(struct radeon_device *rdev,
>         if (r)
>                 DRM_ERROR("ib ring test failed (%d).\n", r);
>
> +       r = radeon_gem_debugfs_init(rdev);
> +       if (r) {
> +               DRM_ERROR("registering gem debugfs failed (%d).\n", r);
> +       }
> +
>         if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
>                 /* Acceleration not working on AGP card try again
>                  * 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 fe5c1f6..87f8c52 100644
> --- a/drivers/gpu/drm/radeon/radeon_gem.c
> +++ b/drivers/gpu/drm/radeon/radeon_gem.c
> @@ -84,6 +84,7 @@ retry:
>                 return r;
>         }
>         *obj = &robj->gem_base;
> +       robj->pid = task_pid_nr(current);
>
>         mutex_lock(&rdev->gem.mutex);
>         list_add_tail(&robj->list, &rdev->gem.objects);
> @@ -575,3 +576,52 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv,
>  {
>         return drm_gem_handle_delete(file_priv, handle);
>  }
> +
> +#if defined(CONFIG_DEBUG_FS)
> +static int radeon_debugfs_gem_info(struct seq_file *m, void *data)
> +{
> +       struct drm_info_node *node = (struct drm_info_node *)m->private;
> +       struct drm_device *dev = node->minor->dev;
> +       struct radeon_device *rdev = dev->dev_private;
> +       struct radeon_bo *rbo;
> +       unsigned i = 0;
> +
> +       mutex_lock(&rdev->gem.mutex);
> +       list_for_each_entry(rbo, &rdev->gem.objects, list) {
> +               unsigned domain;
> +               const char *placement;
> +
> +               domain = radeon_mem_type_to_domain(rbo->tbo.mem.mem_type);
> +               switch (domain) {
> +               case RADEON_GEM_DOMAIN_VRAM:
> +                       placement = "VRAM";
> +                       break;
> +               case RADEON_GEM_DOMAIN_GTT:
> +                       placement = " GTT";
> +                       break;
> +               case RADEON_GEM_DOMAIN_CPU:
> +               default:
> +                       placement = " CPU";
> +                       break;
> +               }
> +               seq_printf(m, "bo[0x%08x] %8dkB %8dMB %s pid %8ld\n",
> +                          i, radeon_bo_size(rbo) >> 10, radeon_bo_size(rbo) >> 20,
> +                          placement, (unsigned long)rbo->pid);
> +               i++;
> +       }
> +       mutex_unlock(&rdev->gem.mutex);
> +       return 0;
> +}
> +
> +static struct drm_info_list radeon_debugfs_gem_list[] = {
> +       {"radeon_gem_info", &radeon_debugfs_gem_info, 0, NULL},
> +};
> +#endif
> +
> +int radeon_gem_debugfs_init(struct radeon_device *rdev)
> +{
> +#if defined(CONFIG_DEBUG_FS)
> +       return radeon_debugfs_add_files(rdev, radeon_debugfs_gem_list, 1);
> +#endif
> +       return 0;
> +}
> --
> 1.8.2.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 18904fb..bd28ee6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -358,7 +358,8 @@  struct radeon_bo {
 	struct radeon_device		*rdev;
 	struct drm_gem_object		gem_base;
 
-	struct ttm_bo_kmap_obj dma_buf_vmap;
+	struct ttm_bo_kmap_obj		dma_buf_vmap;
+	pid_t				pid;
 };
 #define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base)
 
@@ -372,6 +373,8 @@  struct radeon_bo_list {
 	u32			tiling_flags;
 };
 
+int radeon_gem_debugfs_init(struct radeon_device *rdev);
+
 /* sub-allocation manager, it has to be protected by another lock.
  * By conception this is an helper for other part of the driver
  * 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 62d0ba3..76166ae 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1142,6 +1142,11 @@  int radeon_device_init(struct radeon_device *rdev,
 	if (r)
 		DRM_ERROR("ib ring test failed (%d).\n", r);
 
+	r = radeon_gem_debugfs_init(rdev);
+	if (r) {
+		DRM_ERROR("registering gem debugfs failed (%d).\n", r);
+	}
+
 	if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
 		/* Acceleration not working on AGP card try again
 		 * 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 fe5c1f6..87f8c52 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -84,6 +84,7 @@  retry:
 		return r;
 	}
 	*obj = &robj->gem_base;
+	robj->pid = task_pid_nr(current);
 
 	mutex_lock(&rdev->gem.mutex);
 	list_add_tail(&robj->list, &rdev->gem.objects);
@@ -575,3 +576,52 @@  int radeon_mode_dumb_destroy(struct drm_file *file_priv,
 {
 	return drm_gem_handle_delete(file_priv, handle);
 }
+
+#if defined(CONFIG_DEBUG_FS)
+static int radeon_debugfs_gem_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *)m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_bo *rbo;
+	unsigned i = 0;
+
+	mutex_lock(&rdev->gem.mutex);
+	list_for_each_entry(rbo, &rdev->gem.objects, list) {
+		unsigned domain;
+		const char *placement;
+
+		domain = radeon_mem_type_to_domain(rbo->tbo.mem.mem_type);
+		switch (domain) {
+		case RADEON_GEM_DOMAIN_VRAM:
+			placement = "VRAM";
+			break;
+		case RADEON_GEM_DOMAIN_GTT:
+			placement = " GTT";
+			break;
+		case RADEON_GEM_DOMAIN_CPU:
+		default:
+			placement = " CPU";
+			break;
+		}
+		seq_printf(m, "bo[0x%08x] %8dkB %8dMB %s pid %8ld\n",
+			   i, radeon_bo_size(rbo) >> 10, radeon_bo_size(rbo) >> 20,
+			   placement, (unsigned long)rbo->pid);
+		i++;
+	}
+	mutex_unlock(&rdev->gem.mutex);
+	return 0;
+}
+
+static struct drm_info_list radeon_debugfs_gem_list[] = {
+	{"radeon_gem_info", &radeon_debugfs_gem_info, 0, NULL},
+};
+#endif
+
+int radeon_gem_debugfs_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+	return radeon_debugfs_add_files(rdev, radeon_debugfs_gem_list, 1);
+#endif
+	return 0;
+}