diff options
author | Eric Anholt <eric@anholt.net> | 2015-05-15 12:44:55 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2015-06-04 14:15:36 -0700 |
commit | e624e229ca70b4285da4063bd6261639e3df37d6 (patch) | |
tree | 7ac800b10cece0238fcff4b9fb686a29f3bbf3ab | |
parent | 006708c9879d3951edcec2a74021afc41ac65084 (diff) | |
download | linux-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.c | 77 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_debugfs.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 1 |
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); |