[Intel-gfx] [PATCH 1/2] drm/i915: Implement wait-time accounting for i915

Chris Wilson chris at chris-wilson.co.uk
Sun Jul 5 17:37:37 CEST 2009


If we rely on the tracepoint architecture to report the backtrace --
there are rumours that it works for some people... Then we can discard
most of the patch and only add the tracepoint + measurement.

>From 30abd5bc0aad962c5c0cdc5d1ca1780a1e88780d Mon Sep 17 00:00:00 2001
From: Ben Gamari <bgamari.foss at gmail.com>
Date: Sun, 5 Jul 2009 16:32:42 +0100
Subject: [PATCH] drm/i915: Implement wait-time accounting for i915

Implement a mechanism for tracking CPU waits. This will hopefully aid in
identifying GPU stalls. Likely wait-points are surrounded with a pair of
I915_BEGIN_WAIT/I915_END_WAIT macros which times the enclosed region,
invoking a tracepoint reporting the wait. Thanks to ickle for the
guidance in creating this patch.

Signed-off-by: Ben Gamari <bgamari.foss at gmail.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.oc.uk>
---
 drivers/gpu/drm/Kconfig               |    9 +++++++++
 drivers/gpu/drm/i915/i915_drv.h       |    5 +++++
 drivers/gpu/drm/i915/i915_gem.c       |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_gem_debug.c |   11 +++++++++++
 init/Kconfig                          |    2 +-
 5 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 39b393d..ac2552a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -111,6 +111,15 @@ config DRM_I915_KMS
 	  the driver to bind to PCI devices, which precludes loading things
 	  like intelfb.
 
+config DRM_I915_WAIT_ACCOUNTING
+	bool "Enable i915 wait accounting"
+	depends on DRM_I915
+	select TRACING
+	help
+	  Choose this option if you want to enable wait accounting in the i915
+	  driver. This is used to identify performance problems within the
+	  driver. If unsure, say N.
+
 endchoice
 
 config DRM_MGA
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f4d9a16..1fe36a3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -715,6 +715,11 @@ void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj);
 void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj);
 
 /* i915_gem_debug.c */
+#ifdef CONFIG_DRM_I915_WAIT_ACCOUNTING
+void i915_wait_event(int duration);
+#else
+static inline void i915_wait_event(int duration) {}
+#endif
 void i915_gem_dump_object(struct drm_gem_object *obj, int len,
 			  const char *where, uint32_t mark);
 #if WATCH_INACTIVE
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 15acf08..454d360 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -32,6 +32,22 @@
 #include <linux/swap.h>
 #include <linux/pci.h>
 
+#ifdef CONFIG_DRM_I915_WAIT_ACCOUNTING
+#define I915_MIGHT_WAIT() struct timeval _wait_ts_begin, _wait_ts_end
+#define I915_BEGIN_WAIT() do_gettimeofday(&_wait_ts_begin)
+#define I915_END_WAIT() do { \
+	long t__; \
+	t__ = _wait_ts_end.tv_usec - _wait_ts_begin.tv_usec \
+	    + 1000000*(_wait_ts_end.tv_sec - _wait_ts_begin.tv_sec);\
+	do_gettimeofday(&_wait_ts_end); \
+	i915_wait_event(t__); \
+} while (0)
+#else
+#define I915_MIGHT_WAIT()
+#define I915_BEGIN_WAIT()
+#define I915_END_WAIT()
+#endif
+
 #define I915_GEM_GPU_DOMAINS	(~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
 
 static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
@@ -1749,6 +1765,8 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
 	BUG_ON(seqno == 0);
 
 	if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
+		I915_MIGHT_WAIT();
+
 		if (IS_IGDNG(dev))
 			ier = I915_READ(DEIER) | I915_READ(GTIER);
 		else
@@ -1760,6 +1778,8 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
 			i915_driver_irq_postinstall(dev);
 		}
 
+		I915_BEGIN_WAIT();
+
 		dev_priv->mm.waiting_gem_seqno = seqno;
 		i915_user_irq_get(dev);
 		ret = wait_event_interruptible(dev_priv->irq_queue,
@@ -1768,6 +1788,9 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
 					       dev_priv->mm.wedged);
 		i915_user_irq_put(dev);
 		dev_priv->mm.waiting_gem_seqno = 0;
+
+		if (ret == 0)
+			I915_END_WAIT();
 	}
 	if (dev_priv->mm.wedged)
 		ret = -EIO;
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
index 79198b0..8d39446 100644
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -30,6 +30,17 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+#ifdef CONFIG_DRM_I915_WAIT_ACCOUNTING
+#include "trace/i915.h"
+DEFINE_TRACE(i915_wait);
+
+void
+i915_wait_event(int duration)
+{
+    trace_i915_wait(duration);
+}
+#endif
+
 #if WATCH_INACTIVE
 void
 i915_verify_inactive(struct drm_device *dev, char *file, int line)
-- 
1.6.3.3






More information about the Intel-gfx mailing list