[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