All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Subject: [Intel-gfx] [PATCH 10/22] drm/i915/gt: Enable busy-stats for ring-scheduler
Date: Thu,  4 Jun 2020 11:37:39 +0100	[thread overview]
Message-ID: <20200604103751.18816-10-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20200604103751.18816-1-chris@chris-wilson.co.uk>

Couple up the context in/out accounting to record how long each engine
is busy handling requests. This is exposed to userspace for more accurate
measurements, and also enables our soft-rps timer.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_engine_stats.h  | 49 ++++++++++
 drivers/gpu/drm/i915/gt/intel_lrc.c           | 34 +------
 .../gpu/drm/i915/gt/intel_ring_scheduler.c    |  4 +
 drivers/gpu/drm/i915/gt/selftest_engine_pm.c  | 90 +++++++++++++++++++
 drivers/gpu/drm/i915/gt/selftest_rps.c        |  5 ++
 5 files changed, 149 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/intel_engine_stats.h

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_stats.h b/drivers/gpu/drm/i915/gt/intel_engine_stats.h
new file mode 100644
index 000000000000..58491eae3482
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/intel_engine_stats.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ */
+
+#ifndef __INTEL_ENGINE_STATS_H__
+#define __INTEL_ENGINE_STATS_H__
+
+#include <linux/atomic.h>
+#include <linux/ktime.h>
+#include <linux/seqlock.h>
+
+#include "i915_gem.h" /* GEM_BUG_ON */
+#include "intel_engine.h"
+
+static inline void intel_engine_context_in(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	if (atomic_add_unless(&engine->stats.active, 1, 0))
+		return;
+
+	write_seqlock_irqsave(&engine->stats.lock, flags);
+	if (!atomic_add_unless(&engine->stats.active, 1, 0)) {
+		engine->stats.start = ktime_get();
+		atomic_inc(&engine->stats.active);
+	}
+	write_sequnlock_irqrestore(&engine->stats.lock, flags);
+}
+
+static inline void intel_engine_context_out(struct intel_engine_cs *engine)
+{
+	unsigned long flags;
+
+	GEM_BUG_ON(!atomic_read(&engine->stats.active));
+
+	if (atomic_add_unless(&engine->stats.active, -1, 1))
+		return;
+
+	write_seqlock_irqsave(&engine->stats.lock, flags);
+	if (atomic_dec_and_test(&engine->stats.active)) {
+		engine->stats.total =
+			ktime_add(engine->stats.total,
+				  ktime_sub(ktime_get(), engine->stats.start));
+	}
+	write_sequnlock_irqrestore(&engine->stats.lock, flags);
+}
+
+#endif /* __INTEL_ENGINE_STATS_H__ */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index d95b5261f59f..10d83d6327b1 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -139,6 +139,7 @@
 #include "i915_vgpu.h"
 #include "intel_context.h"
 #include "intel_engine_pm.h"
+#include "intel_engine_stats.h"
 #include "intel_gt.h"
 #include "intel_gt_pm.h"
 #include "intel_gt_requests.h"
@@ -1187,39 +1188,6 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status)
 				   status, rq);
 }
 
-static void intel_engine_context_in(struct intel_engine_cs *engine)
-{
-	unsigned long flags;
-
-	if (atomic_add_unless(&engine->stats.active, 1, 0))
-		return;
-
-	write_seqlock_irqsave(&engine->stats.lock, flags);
-	if (!atomic_add_unless(&engine->stats.active, 1, 0)) {
-		engine->stats.start = ktime_get();
-		atomic_inc(&engine->stats.active);
-	}
-	write_sequnlock_irqrestore(&engine->stats.lock, flags);
-}
-
-static void intel_engine_context_out(struct intel_engine_cs *engine)
-{
-	unsigned long flags;
-
-	GEM_BUG_ON(!atomic_read(&engine->stats.active));
-
-	if (atomic_add_unless(&engine->stats.active, -1, 1))
-		return;
-
-	write_seqlock_irqsave(&engine->stats.lock, flags);
-	if (atomic_dec_and_test(&engine->stats.active)) {
-		engine->stats.total =
-			ktime_add(engine->stats.total,
-				  ktime_sub(ktime_get(), engine->stats.start));
-	}
-	write_sequnlock_irqrestore(&engine->stats.lock, flags);
-}
-
 static void
 execlists_check_context(const struct intel_context *ce,
 			const struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c b/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
index c8cd435d1c51..aaff554865b1 100644
--- a/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
+++ b/drivers/gpu/drm/i915/gt/intel_ring_scheduler.c
@@ -9,6 +9,7 @@
 
 #include "i915_drv.h"
 #include "intel_context.h"
+#include "intel_engine_stats.h"
 #include "intel_gt.h"
 #include "intel_gt_pm.h"
 #include "intel_gt_requests.h"
@@ -59,6 +60,7 @@ static struct i915_request *
 schedule_in(struct intel_engine_cs *engine, struct i915_request *rq)
 {
 	__intel_gt_pm_get(engine->gt);
+	intel_engine_context_in(engine);
 	return i915_request_get(rq);
 }
 
@@ -71,6 +73,7 @@ schedule_out(struct intel_engine_cs *engine, struct i915_request *rq)
 		intel_engine_add_retire(engine, ce->timeline);
 
 	i915_request_put(rq);
+	intel_engine_context_out(engine);
 	intel_gt_pm_put_async(engine->gt);
 }
 
@@ -747,6 +750,7 @@ int intel_ring_scheduler_setup(struct intel_engine_cs *engine)
 	engine->legacy.ring = ring;
 
 	engine->flags |= I915_ENGINE_NEEDS_BREADCRUMB_TASKLET;
+	engine->flags |= I915_ENGINE_SUPPORTS_STATS;
 
 	/* Finally, take ownership and responsibility for cleanup! */
 	engine->release = ring_release;
diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
index cbf6b0735272..fef9709b7cfa 100644
--- a/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/selftest_engine_pm.c
@@ -7,6 +7,95 @@
 #include "i915_selftest.h"
 #include "selftest_engine.h"
 #include "selftests/igt_atomic.h"
+#include "selftests/igt_flush_test.h"
+#include "selftests/igt_spinner.h"
+
+static int live_engine_busy_stats(void *arg)
+{
+	struct intel_gt *gt = arg;
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+	struct igt_spinner spin;
+	int err = 0;
+
+	/*
+	 * Check that if an engine supports busy-stats, they tell the truth.
+	 */
+
+	if (igt_spinner_init(&spin, gt))
+		return -ENOMEM;
+
+	GEM_BUG_ON(intel_gt_pm_is_awake(gt));
+	for_each_engine(engine, gt, id) {
+		struct i915_request *rq;
+		ktime_t dt, de;
+
+		if (!intel_engine_supports_stats(engine))
+			continue;
+
+		if (!intel_engine_can_store_dword(engine))
+			continue;
+
+		if (intel_gt_pm_wait_for_idle(gt)) {
+			err = -EBUSY;
+			break;
+		}
+
+		preempt_disable();
+		dt = ktime_get();
+		de = intel_engine_get_busy_time(engine);
+		udelay(100);
+		dt = ktime_sub(ktime_get(), dt);
+		de = ktime_sub(intel_engine_get_busy_time(engine), de);
+		preempt_enable();
+		if (de > 10) {
+			pr_err("%s: reported %lldns [%d%%] busyness while sleeping [for %lldns]\n",
+			       engine->name,
+			       de, (int)div64_u64(100 * de, dt), dt);
+			err = -EINVAL;
+			break;
+		}
+
+		rq = igt_spinner_create_request(&spin,
+						engine->kernel_context,
+						MI_NOOP);
+		if (IS_ERR(rq)) {
+			err = PTR_ERR(rq);
+			break;
+		}
+		i915_request_add(rq);
+
+		if (!igt_wait_for_spinner(&spin, rq)) {
+			intel_gt_set_wedged(engine->gt);
+			err = -ETIME;
+			break;
+		}
+
+		preempt_disable();
+		dt = ktime_get();
+		de = intel_engine_get_busy_time(engine);
+		udelay(100);
+		dt = ktime_sub(ktime_get(), dt);
+		de = ktime_sub(intel_engine_get_busy_time(engine), de);
+		preempt_enable();
+		if (100 * de < 95 * dt) {
+			pr_err("%s: reported only %lldns [%d%%] busyness while spinning [for %lldns]\n",
+			       engine->name,
+			       de, (int)div64_u64(100 * de, dt), dt);
+			err = -EINVAL;
+			break;
+		}
+
+		igt_spinner_end(&spin);
+		if (igt_flush_test(gt->i915)) {
+			err = -EIO;
+			break;
+		}
+	}
+
+	igt_spinner_fini(&spin);
+	return err;
+}
 
 static int live_engine_pm(void *arg)
 {
@@ -77,6 +166,7 @@ static int live_engine_pm(void *arg)
 int live_engine_pm_selftests(struct intel_gt *gt)
 {
 	static const struct i915_subtest tests[] = {
+		SUBTEST(live_engine_busy_stats),
 		SUBTEST(live_engine_pm),
 	};
 
diff --git a/drivers/gpu/drm/i915/gt/selftest_rps.c b/drivers/gpu/drm/i915/gt/selftest_rps.c
index 5049c3dd08a6..5e364fb31aea 100644
--- a/drivers/gpu/drm/i915/gt/selftest_rps.c
+++ b/drivers/gpu/drm/i915/gt/selftest_rps.c
@@ -1252,6 +1252,11 @@ int live_rps_dynamic(void *arg)
 	if (igt_spinner_init(&spin, gt))
 		return -ENOMEM;
 
+	if (intel_rps_has_interrupts(rps))
+		pr_info("RPS has interrupt support\n");
+	if (intel_rps_uses_timer(rps))
+		pr_info("RPS has timer support\n");
+
 	for_each_engine(engine, gt, id) {
 		struct i915_request *rq;
 		struct {
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2020-06-04 10:38 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-04 10:37 [Intel-gfx] [PATCH 01/22] drm/i915/gem: Mark the buffer pool as active for the cmdparser Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 02/22] drm/i915: Trim set_timer_ms() intervals Chris Wilson
2020-06-04 12:54   ` Matthew Auld
2020-06-04 10:37 ` [Intel-gfx] [PATCH 03/22] drm/i915/gt: Set timeslicing priority from queue Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 04/22] drm/i915/gt: Always check to enable timeslicing if not submitting Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 05/22] Restore "drm/i915: drop engine_pin/unpin_breadcrumbs_irq" Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 06/22] drm/i915/gt: Couple tasklet scheduling for all CS interrupts Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 07/22] drm/i915/gt: Support creation of 'internal' rings Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 08/22] drm/i915/gt: Use client timeline address for seqno writes Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 09/22] drm/i915/gt: Infrastructure for ring scheduling Chris Wilson
2020-06-04 10:37 ` Chris Wilson [this message]
2020-06-04 10:37 ` [Intel-gfx] [PATCH 11/22] drm/i915/gt: Track if an engine requires forcewake w/a Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 12/22] drm/i915/gt: Implement ring scheduler for gen6/7 Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 13/22] drm/i915/gt: Enable ring scheduling " Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 14/22] drm/i915/gem: Async GPU relocations only Chris Wilson
2020-06-04 13:37   ` Matthew Auld
2020-06-04 13:44     ` Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 15/22] drm/i915: Add list_for_each_entry_safe_continue_reverse Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 16/22] drm/i915/gem: Separate reloc validation into an earlier step Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 17/22] drm/i915/gem: Lift GPU relocation allocation Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 18/22] drm/i915/gem: Build the reloc request first Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 19/22] drm/i915/gem: Add all GPU reloc awaits/signals en masse Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 20/22] dma-buf: Proxy fence, an unsignaled fence placeholder Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 21/22] drm/i915: Unpeel awaits on a proxy fence Chris Wilson
2020-06-04 10:37 ` [Intel-gfx] [PATCH 22/22] drm/i915/gem: Make relocations atomic within execbuf Chris Wilson
2020-06-04 11:36 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/22] drm/i915/gem: Mark the buffer pool as active for the cmdparser Patchwork
2020-06-04 11:37 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-06-04 12:06 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2020-06-04 12:49 ` [Intel-gfx] [PATCH 01/22] " Matthew Auld

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200604103751.18816-10-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.