[Mesa-dev] [PATCH 2/4] radeon: Add bo statistics dumping support

Lauri Kasanen cand at gmx.com
Tue Jan 7 10:11:51 PST 2014


No measurable overhead when off (glxgears within 0.5%).

v2: Cosmetic changes.
v3: Moved file handling into winsys

Signed-off-by: Lauri Kasanen <cand at gmx.com>
---
 src/gallium/drivers/radeon/r600_pipe_common.c     |  5 ++++
 src/gallium/drivers/radeon/r600_pipe_common.h     |  1 +
 src/gallium/winsys/radeon/drm/radeon_drm_bo.c     | 16 +++++++++++
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c     |  9 ++++++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c | 35 +++++++++++++++++++++++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h |  2 ++
 src/gallium/winsys/radeon/drm/radeon_winsys.h     |  5 ++++
 7 files changed, 73 insertions(+)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 28921be..f2a5794 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -38,6 +38,7 @@ static const struct debug_named_value common_debug_options[] = {
 	{ "compute", DBG_COMPUTE, "Print compute info" },
 	{ "vm", DBG_VM, "Print virtual addresses when creating resources" },
 	{ "trace_cs", DBG_TRACE_CS, "Trace cs and write rlockup_<csid>.c file with faulty cs" },
+	{ "bostats", DBG_BO_STATS, "Write bo statistics to /tmp/bostats.<pid>[.name]" },
 
 	/* shaders */
 	{ "fs", DBG_FS, "Print fetch shaders" },
@@ -209,6 +210,10 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen,
 		return false;
 	}
 
+	if (rscreen->debug_flags & DBG_BO_STATS) {
+		ws->enable_bo_stats(ws);
+	}
+
 	util_format_s3tc_init();
 
 	pipe_mutex_init(rscreen->aux_context_lock);
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index bf0b968..4c35e66 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -67,6 +67,7 @@
 #define DBG_COMPUTE		(1 << 2)
 #define DBG_VM			(1 << 3)
 #define DBG_TRACE_CS		(1 << 4)
+#define DBG_BO_STATS		(1 << 5)
 /* shaders */
 #define DBG_FS			(1 << 8)
 #define DBG_VS			(1 << 9)
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index ca569a1..ea99351 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -370,6 +370,7 @@ static void radeon_bo_destroy(struct pb_buffer *_buf)
 {
     struct radeon_bo *bo = radeon_bo(_buf);
     struct radeon_bomgr *mgr = bo->mgr;
+    struct radeon_drm_winsys *ws = mgr->rws;
     struct drm_gem_close args;
 
     memset(&args, 0, sizeof(args));
@@ -399,6 +400,11 @@ static void radeon_bo_destroy(struct pb_buffer *_buf)
         bo->rws->allocated_vram -= align(bo->base.size, 4096);
     else if (bo->initial_domain & RADEON_DOMAIN_GTT)
         bo->rws->allocated_gtt -= align(bo->base.size, 4096);
+
+    if (ws->bo_stats_file) {
+        fprintf(ws->bo_stats_file, "%p destroyed @%llu\n", bo, stats_time_get(ws));
+    }
+
     FREE(bo);
 }
 
@@ -450,6 +456,7 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
 {
     struct radeon_bo *bo = (struct radeon_bo*)buf;
     struct radeon_drm_cs *cs = (struct radeon_drm_cs*)rcs;
+    struct radeon_drm_winsys *ws = bo->mgr->rws;
 
     /* If it's not unsynchronized bo_map, flush CS if needed and then wait. */
     if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
@@ -518,6 +525,10 @@ static void *radeon_bo_map(struct radeon_winsys_cs_handle *buf,
         }
     }
 
+    if (ws->bo_stats_file) {
+        fprintf(ws->bo_stats_file, "%p cpu mapped @%llu\n", bo, stats_time_get(ws));
+    }
+
     return radeon_bo_do_map(bo);
 }
 
@@ -636,6 +647,11 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
     else if (rdesc->initial_domains & RADEON_DOMAIN_GTT)
         rws->allocated_gtt += align(size, 4096);
 
+    if (rws->bo_stats_file) {
+        fprintf(rws->bo_stats_file, "%p created, size %u, prio %u, @%llu\n", bo, size,
+                                   bo->stats.high_prio, stats_time_get(rws));
+    }
+
     return &bo->base;
 }
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index d8ad297..845603d 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -344,6 +344,7 @@ static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs,
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     struct radeon_bo *bo = (struct radeon_bo*)buf;
+    struct radeon_drm_winsys *ws = cs->ws;
     enum radeon_bo_domain added_domains;
     unsigned index = radeon_add_reloc(cs, bo, usage, domains, &added_domains);
 
@@ -352,6 +353,14 @@ static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs,
     if (added_domains & RADEON_DOMAIN_VRAM)
         cs->csc->used_vram += bo->base.size;
 
+    if (ws->bo_stats_file) {
+        if (usage & RADEON_USAGE_WRITE) {
+            fprintf(ws->bo_stats_file, "%p write @%llu\n", bo, stats_time_get(ws));
+        } else {
+            fprintf(ws->bo_stats_file, "%p read @%llu\n", bo, stats_time_get(ws));
+        }
+    }
+
     return index;
 }
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 7bedf92..bb17a21 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -45,6 +45,13 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#ifdef __GLIBC__
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <errno.h>
+#endif
+
 /*
  * this are copy from radeon_drm, once an updated libdrm is released
  * we should bump configure.ac requirement for it and remove the following
@@ -445,6 +452,12 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
     ws->kill_timing_thread = 1;
     pipe_thread_wait(ws->timing_thread);
 
+    if (ws->bo_stats_file) {
+        fflush(ws->bo_stats_file);
+        fclose(ws->bo_stats_file);
+        ws->bo_stats_file = NULL;
+    }
+
     pipe_mutex_destroy(ws->hyperz_owner_mutex);
     pipe_mutex_destroy(ws->cmask_owner_mutex);
     pipe_mutex_destroy(ws->cs_stack_lock);
@@ -530,6 +543,27 @@ static uint64_t radeon_query_value(struct radeon_winsys *rws,
     return 0;
 }
 
+static void radeon_enable_bo_stats(struct radeon_winsys *rws)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+
+    char statsfile[80];
+    const pid_t pid = getpid();
+
+#ifdef __GLIBC__
+    snprintf(statsfile, 80, "/tmp/bostats.%u.%s", pid, program_invocation_short_name);
+#else
+    snprintf(statsfile, 80, "/tmp/bostats.%u", pid);
+#endif
+
+    ws->bo_stats_file = fopen(statsfile, "w");
+    if (!ws->bo_stats_file)
+        fprintf(stderr, "Failed to open bo stats file %s\n", statsfile);
+    else
+        fprintf(ws->bo_stats_file, "started @%llu\n",
+            stats_time_get(ws));
+}
+
 static unsigned hash_fd(void *key)
 {
     int fd = pointer_to_intptr(key);
@@ -666,6 +700,7 @@ PUBLIC struct radeon_winsys *radeon_drm_winsys_create(int fd)
     ws->base.surface_init = radeon_drm_winsys_surface_init;
     ws->base.surface_best = radeon_drm_winsys_surface_best;
     ws->base.query_value = radeon_query_value;
+    ws->base.enable_bo_stats = radeon_enable_bo_stats;
 
     radeon_bomgr_init_functions(ws);
     radeon_drm_cs_init_functions(ws);
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 01c2d9c..7d93960 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -77,6 +77,8 @@ struct radeon_drm_winsys {
     pipe_thread timing_thread;
     int kill_timing_thread;
     uint64_t time;
+
+    FILE *bo_stats_file;
 };
 
 static INLINE struct radeon_drm_winsys *
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 55f60d3..bee22f8 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -536,6 +536,11 @@ struct radeon_winsys {
 
     uint64_t (*query_value)(struct radeon_winsys *ws,
                             enum radeon_value_id value);
+
+    /**
+     * Enable bo statistics logging.
+     */
+    void (*enable_bo_stats)(struct radeon_winsys *ws);
 };
 
 /**
-- 
1.8.3.1



More information about the mesa-dev mailing list