summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-05-15 12:44:55 -0700
committerEric Anholt <eric@anholt.net>2015-06-04 14:15:36 -0700
commite624e229ca70b4285da4063bd6261639e3df37d6 (patch)
tree7ac800b10cece0238fcff4b9fb686a29f3bbf3ab
parent006708c9879d3951edcec2a74021afc41ac65084 (diff)
downloadlinux-e624e229ca70b4285da4063bd6261639e3df37d6.tar.gz
drm/vc4: Add a debugfs node for looking at BO allocation stats.
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c77
-rw-r--r--drivers/gpu/drm/vc4/vc4_debugfs.c1
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h1
3 files changed, 68 insertions, 11 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index aa063eb4889f..ba91b7c17ab1 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -18,12 +18,37 @@
#include "vc4_drv.h"
#include "uapi/drm/vc4_drm.h"
+static struct {
+ u32 num_allocated;
+ u32 size_allocated;
+ u32 num_cached;
+ u32 size_cached;
+} bo_stats;
+
static uint32_t
bo_page_index(size_t size)
{
return (size / PAGE_SIZE) - 1;
}
+static void
+vc4_bo_destroy(struct vc4_bo *bo)
+{
+ bo_stats.num_allocated--;
+ bo_stats.size_allocated -= bo->base.base.size;
+ drm_gem_cma_free_object(&bo->base.base);
+}
+
+static void
+vc4_bo_remove_from_cache(struct vc4_bo *bo)
+{
+ bo_stats.num_cached--;
+ bo_stats.size_cached -= bo->base.base.size;
+
+ list_del(&bo->unref_head);
+ list_del(&bo->size_head);
+}
+
static struct list_head *
vc4_get_cache_list_for_size(struct drm_device *dev, size_t size)
{
@@ -71,9 +96,8 @@ vc4_bo_cache_purge(struct drm_device *dev)
while (!list_empty(&vc4->bo_cache.time_list)) {
struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
struct vc4_bo, unref_head);
- list_del(&bo->unref_head);
- list_del(&bo->size_head);
- drm_gem_cma_free_object(&bo->base.base);
+ vc4_bo_remove_from_cache(bo);
+ vc4_bo_destroy(bo);
}
}
@@ -90,8 +114,7 @@ vc4_bo_create(struct drm_device *dev, size_t size)
if (!list_empty(&vc4->bo_cache.size_list[page_index])) {
bo = list_first_entry(&vc4->bo_cache.size_list[page_index],
struct vc4_bo, size_head);
- list_del(&bo->size_head);
- list_del(&bo->unref_head);
+ vc4_bo_remove_from_cache(bo);
}
}
if (bo) {
@@ -111,6 +134,9 @@ vc4_bo_create(struct drm_device *dev, size_t size)
return NULL;
}
+ bo_stats.num_allocated++;
+ bo_stats.size_allocated += size;
+
return to_vc4_bo(&cma_obj->base);
}
@@ -157,9 +183,8 @@ vc4_bo_cache_free_old(struct drm_device *dev)
return;
}
- list_del(&bo->unref_head);
- list_del(&bo->size_head);
- drm_gem_cma_free_object(&bo->base.base);
+ vc4_bo_remove_from_cache(bo);
+ vc4_bo_destroy(bo);
}
}
@@ -179,19 +204,19 @@ vc4_free_object(struct drm_gem_object *gem_bo)
/* If the object references someone else's memory, we can't cache it.
*/
if (gem_bo->import_attach) {
- drm_gem_cma_free_object(gem_bo);
+ vc4_bo_destroy(bo);
return;
}
/* Don't cache if it was publicly named. */
if (gem_bo->name) {
- drm_gem_cma_free_object(gem_bo);
+ vc4_bo_destroy(bo);
return;
}
cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size);
if (!cache_list) {
- drm_gem_cma_free_object(gem_bo);
+ vc4_bo_destroy(bo);
return;
}
@@ -208,6 +233,9 @@ vc4_free_object(struct drm_gem_object *gem_bo)
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
+ bo_stats.num_cached++;
+ bo_stats.size_cached += gem_bo->size;
+
vc4_bo_cache_free_old(dev);
}
@@ -318,3 +346,30 @@ vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
drm_gem_object_unreference(gem_obj);
return 0;
}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+
+ mutex_lock(&dev->struct_mutex);
+
+ seq_printf(m, "num bos allocated: %d\n",
+ bo_stats.num_allocated);
+ seq_printf(m, "size bos allocated: %dkb\n",
+ bo_stats.size_allocated / 1024);
+ seq_printf(m, "num bos used: %d\n",
+ bo_stats.num_allocated - bo_stats.num_cached);
+ seq_printf(m, "size bos used: %dkb\n",
+ (bo_stats.size_allocated - bo_stats.size_cached) / 1024);
+ seq_printf(m, "num bos cached: %d\n",
+ bo_stats.num_cached);
+ seq_printf(m, "size bos cached: %dkb\n",
+ bo_stats.size_cached / 1024);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+#endif
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
index abd541f470ca..ca4743126736 100644
--- a/drivers/gpu/drm/vc4/vc4_debugfs.c
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -16,6 +16,7 @@
#include "vc4_regs.h"
static const struct drm_info_list vc4_debugfs_list[] = {
+ {"bo_stats", vc4_bo_stats_debugfs, 0},
{"v3d_ident", vc4_v3d_debugfs_ident, 0},
{"v3d_regs", vc4_v3d_debugfs_regs, 0},
{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index aa6592dd1fc9..fa14c801b1a4 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -366,6 +366,7 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+int vc4_bo_stats_debugfs(struct seq_file *m, void *unused);
/* vc4_debugfs.c */
int vc4_debugfs_init(struct drm_minor *minor);