[Intel-gfx] [PATCH] First stab at doing wait accounting
Ben Gamari
bgamari.foss at gmail.com
Fri May 22 18:38:56 CEST 2009
---
drivers/gpu/drm/i915/i915_drv.h | 25 +++++++++++++++++++++++++
drivers/gpu/drm/i915/i915_gem.c | 17 ++++++++++++++++-
drivers/gpu/drm/i915/i915_gem_debugfs.c | 17 +++++++++++++++++
3 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9b149fe..12cdd38 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -126,6 +126,27 @@ struct drm_i915_fence_reg {
struct drm_gem_object *obj;
};
+enum drm_i915_wait_srcs {
+ I915_WAITSRC_WAIT_FOR_ACTIVE_OBJ,
+ I915_WAITSRC_WAIT_ON_RENDER_FOR_OBJ,
+ I915_WAITSRC_FLUSH_FOR_OBJ,
+ I915_WAITSRC_FLUSH_FOR_FENCE,
+ I915_WAITSRC_LAST
+};
+
+#ifdef WAIT_ACCOUNTING
+#define MIGHT_WAIT() struct timespec _wait_ts_begin, _wait_ts_end;
+#define BEGIN_WAIT() do_gettimeofday(&_wait_ts_begin);
+#define END_WAIT(src) { \
+ do_gettimeofay(&_wait_ts_end); \
+ dev_priv->mm.wait_time[src] += wait_ts_end.tv_usec - wait_ts_begin.tv_usec; \
+ dev_priv->mm.wait_count[src]++; }
+#else
+#define MIGHT_WAIT() {}
+#define BEGIN_WAIT() {}
+#define END_WAIT(src) {}
+#endif
+
typedef struct drm_i915_private {
struct drm_device *dev;
@@ -380,6 +401,10 @@ typedef struct drm_i915_private {
/* storage for physical objects */
struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
+
+ /* wait source accumulators */
+ long int wait_time[I915_WAITSRC_LAST];
+ long int wait_count[I915_WAITSRC_LAST];
} mm;
} drm_i915_private_t;
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b189b49..0017486 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1912,6 +1912,8 @@ i915_gem_evict_something(struct drm_device *dev)
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
int ret = 0;
+ int wait_reason = I915_WAITSRC_WAIT_FOR_ACTIVE_OBJ;
+ MIGHT_WAIT();
for (;;) {
/* If there's an inactive buffer available now, grab it
@@ -1929,7 +1931,10 @@ i915_gem_evict_something(struct drm_device *dev)
BUG_ON(obj_priv->active);
/* Wait on the rendering and unbind the buffer. */
+ BEGIN_WAIT();
ret = i915_gem_object_unbind(obj);
+ if (ret)
+ END_WAIT(I915_WAITSRC_WAIT_ON_RENDER_FOR_OBJ);
break;
}
@@ -1944,9 +1949,11 @@ i915_gem_evict_something(struct drm_device *dev)
struct drm_i915_gem_request,
list);
+ BEGIN_WAIT();
ret = i915_wait_request(dev, request->seqno);
if (ret)
break;
+ END_WAIT(wait_reason);
/* if waiting caused an object to become inactive,
* then loop around and wait for it. Otherwise, we
@@ -1964,11 +1971,14 @@ i915_gem_evict_something(struct drm_device *dev)
* will get moved to inactive.
*/
if (!list_empty(&dev_priv->mm.flushing_list)) {
+ MIGHT_WAIT();
+
obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
struct drm_i915_gem_object,
list);
obj = obj_priv->obj;
-
+
+ wait_reason = I915_WAITSRC_FLUSH_FOR_OBJ;
i915_gem_flush(dev,
obj->write_domain,
obj->write_domain);
@@ -2238,7 +2248,10 @@ try_again:
* objects to finish before trying again.
*/
if (i == dev_priv->num_fence_regs) {
+ MIGHT_WAIT();
+
if (seqno == dev_priv->mm.next_gem_seqno) {
+
i915_gem_flush(dev,
I915_GEM_GPU_DOMAINS,
I915_GEM_GPU_DOMAINS);
@@ -2248,9 +2261,11 @@ try_again:
return -ENOMEM;
}
+ BEGIN_WAIT();
ret = i915_wait_request(dev, seqno);
if (ret)
return ret;
+ END_WAIT(I915_WAITSRC_FLUSH_FOR_FENCE);
goto try_again;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
index 986f108..b28867f 100644
--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c
@@ -323,6 +323,22 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
return 0;
}
+static int i915_wait_source_info(struct seq_file *m, void *data) {
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+#define WAITSRC(SRC) seq_printf(m, "%s\t%ld\t%ld\n", #SRC, \
+ dev_priv->mm.wait_time[I915_WAITSRC_##SRC], \
+ dev_priv->mm.wait_count[I915_WAITSRC_##SRC])
+ WAITSRC(WAIT_FOR_ACTIVE_OBJ);
+ WAITSRC(WAIT_ON_RENDER_FOR_OBJ);
+ WAITSRC(FLUSH_FOR_OBJ);
+ WAITSRC(FLUSH_FOR_FENCE);
+#undef WAITSRC
+
+ return 0;
+}
static struct drm_info_list i915_gem_debugfs_list[] = {
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
@@ -336,6 +352,7 @@ static struct drm_info_list i915_gem_debugfs_list[] = {
{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
{"i915_batchbuffers", i915_batchbuffer_info, 0},
+ {"i915_wait_sources", i915_wait_source_info, 0},
};
#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
--
1.6.2.2
More information about the Intel-gfx
mailing list