[PATCH] pmu underrun test

Tvrtko Ursulin tursulin at ursulin.net
Fri Jun 1 13:06:03 UTC 2018


From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
---
 drivers/gpu/drm/i915/i915_pmu.c         | 42 ++++++++++++++++++++++---
 drivers/gpu/drm/i915/i915_pmu.h         |  5 +++
 drivers/gpu/drm/i915/intel_ringbuffer.h |  2 +-
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index dc87797db500..ed4ee3d48c9f 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -127,9 +127,12 @@ static void __i915_pmu_maybe_start_timer(struct drm_i915_private *i915)
 {
 	if (!i915->pmu.timer_enabled && pmu_needs_timer(i915, true)) {
 		i915->pmu.timer_enabled = true;
+		i915->pmu.timer_sum = 0;
+		i915->pmu.timer_cnt = 0;
+		i915->pmu.timer_last = ktime_get();
 		hrtimer_start_range_ns(&i915->pmu.timer,
 				       ns_to_ktime(PERIOD), 0,
-				       HRTIMER_MODE_REL_PINNED);
+				       HRTIMER_MODE_REL);
 	}
 }
 
@@ -237,14 +240,45 @@ static enum hrtimer_restart i915_sample(struct hrtimer *hrtimer)
 {
 	struct drm_i915_private *i915 =
 		container_of(hrtimer, struct drm_i915_private, pmu.timer);
-
-	if (!READ_ONCE(i915->pmu.timer_enabled))
+	unsigned int urun;
+	ktime_t now;
+
+	if (!READ_ONCE(i915->pmu.timer_enabled)) {
+		if (i915->pmu.timer_cnt) {
+			unsigned long avg = ktime_to_ns(i915->pmu.timer_sum);
+
+			avg /= i915->pmu.timer_cnt;
+
+			if (avg > (110 * PERIOD / 100) ||
+			    avg < (90 * PERIOD / 100))
+				DRM_ERROR("avg period = %luns (cnt=%lu)\n",
+					  avg, i915->pmu.timer_cnt);
+			DRM_DEBUG_DRIVER("avg period = %luns (cnt=%lu)\n",
+					 avg, i915->pmu.timer_cnt);
+			i915->pmu.timer_sum = 0;
+			i915->pmu.timer_cnt = 0;
+		}
 		return HRTIMER_NORESTART;
+	}
+
+	now = ktime_get();
+
+	i915->pmu.timer_sum = ktime_add(i915->pmu.timer_sum,
+					ktime_sub(now, i915->pmu.timer_last));
+	i915->pmu.timer_cnt++;
+	i915->pmu.timer_last = now;
 
 	engines_sample(i915);
 	frequency_sample(i915);
 
-	hrtimer_forward_now(hrtimer, ns_to_ktime(PERIOD));
+	urun = hrtimer_forward(hrtimer, now, ns_to_ktime(PERIOD));
+	if (urun > 1)
+		DRM_ERROR_RATELIMITED("%u timer underrun(s)\n", urun - 1);
+
+	if (ktime_to_ns(ktime_sub(ktime_get(), now)) > (75 * PERIOD / 100))
+		DRM_ERROR_RATELIMITED("timer took %lldns!\n",
+				      ktime_to_ns(ktime_sub(ktime_get(), now)));
+
 	return HRTIMER_RESTART;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_pmu.h b/drivers/gpu/drm/i915/i915_pmu.h
index 2ba735299f7c..a024b867e184 100644
--- a/drivers/gpu/drm/i915/i915_pmu.h
+++ b/drivers/gpu/drm/i915/i915_pmu.h
@@ -65,6 +65,11 @@ struct i915_pmu {
 	 * event types.
 	 */
 	u64 enable;
+
+	ktime_t timer_last;
+	ktime_t timer_sum;
+	unsigned long timer_cnt;
+
 	/**
 	 * @enable_count: Reference counts for the enabled events.
 	 *
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index acef385c4c80..f9a434a1a06e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -642,7 +642,7 @@ intel_engine_needs_cmd_parser(const struct intel_engine_cs *engine)
 static inline bool
 intel_engine_supports_stats(const struct intel_engine_cs *engine)
 {
-	return engine->flags & I915_ENGINE_SUPPORTS_STATS;
+	return 0;//engine->flags & I915_ENGINE_SUPPORTS_STATS;
 }
 
 static inline bool
-- 
2.17.0



More information about the Intel-gfx-trybot mailing list