[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