[Intel-gfx] [PATCH] [drm/i915] Add pwrite and clflush performance counters to /proc/dri

Keith Packard keithp at keithp.com
Thu Nov 20 20:48:20 CET 2008


Count bytes flushed via clflush and bytes written via pwrite to see how much
data we're preparing for the GPU.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    4 +++
 drivers/gpu/drm/i915/i915_gem.c      |   15 ++++++++++
 drivers/gpu/drm/i915/i915_gem_proc.c |   48 ++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9bb6803..f27fc2b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -324,6 +324,10 @@ typedef struct drm_i915_private {
 		uint32_t bit_6_swizzle_x;
 		/** Bit 6 swizzling required for Y tiling */
 		uint32_t bit_6_swizzle_y;
+
+		/** performance counters */
+		atomic64_t clflush_bytes;
+		atomic64_t pwrite_bytes;
 	} mm;
 } drm_i915_private_t;
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index aa8467a..71d3ac1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -272,6 +272,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
 	offset = obj_priv->gtt_offset + args->offset;
 	obj_priv->dirty = 1;
 
+	atomic64_add(remain, &dev_priv->mm.pwrite_bytes);
+
 	while (remain > 0) {
 		/* Operation in this page
 		 *
@@ -1227,6 +1229,8 @@ void
 i915_gem_clflush_object(struct drm_gem_object *obj)
 {
 	struct drm_i915_gem_object	*obj_priv = obj->driver_private;
+	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	/* If we don't have a page list set up, then we're not pinned
 	 * to GPU, and we can ignore the cache flush because it'll happen
@@ -1235,6 +1239,8 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
 	if (obj_priv->page_list == NULL)
 		return;
 
+	atomic64_add(obj->size, &dev_priv->mm.clflush_bytes);
+
 	drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
 }
 
@@ -1318,6 +1324,7 @@ static int
 i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
 {
 	struct drm_device *dev = obj->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
 	int ret;
 
@@ -1337,12 +1344,15 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
 	if (obj->read_domains & I915_GEM_DOMAIN_CPU &&
 	    obj_priv->page_cpu_valid != NULL) {
 		int i;
+		int bytes_flushed = 0;
 
 		for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) {
 			if (obj_priv->page_cpu_valid[i])
 				continue;
+			bytes_flushed += PAGE_SIZE;
 			drm_clflush_pages(obj_priv->page_list + i, 1);
 		}
+		atomic64_add(bytes_flushed, &dev_priv->mm.clflush_bytes);
 
 		drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE,
 			 DRM_MEM_DRIVER);
@@ -1568,7 +1578,9 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
 					  uint64_t offset, uint64_t size)
 {
 	struct drm_i915_gem_object *obj_priv = obj->driver_private;
+	drm_i915_private_t *dev_priv = obj->dev->dev_private;
 	int i, ret;
+	int bytes_flushed = 0;
 
 	i915_gem_object_flush_gpu_write_domain(obj);
 	/* Wait on any GPU rendering and flushing to occur. */
@@ -1597,10 +1609,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
 		if (obj_priv->page_cpu_valid[i])
 			continue;
 
+		bytes_flushed += PAGE_SIZE;
+
 		drm_clflush_pages(obj_priv->page_list + i, 1);
 
 		obj_priv->page_cpu_valid[i] = 1;
 	}
+	atomic64_add(bytes_flushed, &dev_priv->mm.clflush_bytes);
 
 	/* It should now be out of any other write domains, and we can update
 	 * the domain values for our changes.
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
index 4d1b9de..d9e8da8 100644
--- a/drivers/gpu/drm/i915/i915_gem_proc.c
+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
@@ -283,6 +283,52 @@ static int i915_hws_info(char *buf, char **start, off_t offset,
 	return len - offset;
 }
 
+static int i915_gem_clflush_bytes(char *buf, char **start, off_t offset,
+				  int request, int *eof, void *data)
+{
+	struct drm_minor *minor = (struct drm_minor *) data;
+	struct drm_device *dev = minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int len = 0;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+
+	*start = &buf[offset];
+	*eof = 0;
+	DRM_PROC_PRINT("%lld\n", (long long) atomic64_read(&dev_priv->mm.clflush_bytes));
+	if (len > request + offset)
+		return request;
+	*eof = 1;
+	return len - offset;
+}
+
+static int i915_gem_pwrite_bytes(char *buf, char **start, off_t offset,
+				 int request, int *eof, void *data)
+{
+	struct drm_minor *minor = (struct drm_minor *) data;
+	struct drm_device *dev = minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int len = 0;
+
+	if (offset > DRM_PROC_LIMIT) {
+		*eof = 1;
+		return 0;
+	}
+
+
+	*start = &buf[offset];
+	*eof = 0;
+	DRM_PROC_PRINT("%lld\n", (long long) atomic64_read(&dev_priv->mm.pwrite_bytes));
+	if (len > request + offset)
+		return request;
+	*eof = 1;
+	return len - offset;
+}
+
 static struct drm_proc_list {
 	/** file name */
 	const char *name;
@@ -296,6 +342,8 @@ static struct drm_proc_list {
 	{"i915_gem_seqno", i915_gem_seqno_info},
 	{"i915_gem_interrupt", i915_interrupt_info},
 	{"i915_gem_hws", i915_hws_info},
+	{"i915_gem_clflush_bytes", i915_gem_clflush_bytes},
+	{"i915_gem_pwrite_bytes", i915_gem_pwrite_bytes},
 };
 
 #define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
-- 
1.5.6.5




More information about the Intel-gfx mailing list