All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 11/26] drm/i915/selftests: Basic stress test for rapid context switching
Date: Tue, 11 Sep 2018 12:57:55 +0100	[thread overview]
Message-ID: <20180911115810.8917-11-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <20180911115810.8917-1-chris@chris-wilson.co.uk>

We need to exercise the HW and submission paths for switching contexts
rapidly to check that features such as execlists' wa_tail are adequate.
Plus it's an interesting baseline latency metric.

v2: Check the initial request for allocation errors

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 .../gpu/drm/i915/selftests/i915_gem_context.c | 188 ++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
index 1c92560d35da..24734dd91309 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c
@@ -22,6 +22,8 @@
  *
  */
 
+#include <linux/prime_numbers.h>
+
 #include "../i915_selftest.h"
 #include "i915_random.h"
 #include "igt_flush_test.h"
@@ -32,6 +34,191 @@
 
 #define DW_PER_PAGE (PAGE_SIZE / sizeof(u32))
 
+struct live_test {
+	struct drm_i915_private *i915;
+	const char *func;
+	const char *name;
+
+	unsigned int reset_count;
+};
+
+static int begin_live_test(struct live_test *t,
+			   struct drm_i915_private *i915,
+			   const char *func,
+			   const char *name)
+{
+	int err;
+
+	t->i915 = i915;
+	t->func = func;
+	t->name = name;
+
+	err = i915_gem_wait_for_idle(i915,
+				     I915_WAIT_LOCKED,
+				     MAX_SCHEDULE_TIMEOUT);
+	if (err) {
+		pr_err("%s(%s): failed to idle before, with err=%d!",
+		       func, name, err);
+		return err;
+	}
+
+	i915->gpu_error.missed_irq_rings = 0;
+	t->reset_count = i915_reset_count(&i915->gpu_error);
+
+	return 0;
+}
+
+static int end_live_test(struct live_test *t)
+{
+	struct drm_i915_private *i915 = t->i915;
+
+	i915_retire_requests(i915);
+
+	if (wait_for(intel_engines_are_idle(i915), 10)) {
+		pr_err("%s(%s): GPU not idle\n", t->func, t->name);
+		return -EIO;
+	}
+
+	if (t->reset_count != i915_reset_count(&i915->gpu_error)) {
+		pr_err("%s(%s): GPU was reset %d times!\n",
+		       t->func, t->name,
+		       i915_reset_count(&i915->gpu_error) - t->reset_count);
+		return -EIO;
+	}
+
+	if (i915->gpu_error.missed_irq_rings) {
+		pr_err("%s(%s): Missed interrupts on engines %lx\n",
+		       t->func, t->name, i915->gpu_error.missed_irq_rings);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int live_nop_switch(void *arg)
+{
+	const unsigned int nctx = 1024;
+	struct drm_i915_private *i915 = arg;
+	struct intel_engine_cs *engine;
+	struct i915_gem_context **ctx;
+	enum intel_engine_id id;
+	struct drm_file *file;
+	struct live_test t;
+	unsigned long n;
+	int err = -ENODEV;
+
+	/*
+	 * Create as many contexts as we can feasibly get away with
+	 * and check we can switch between them rapidly.
+	 *
+	 * Serves as very simple stress test for submission and HW switching
+	 * between contexts.
+	 */
+
+	if (!DRIVER_CAPS(i915)->has_logical_contexts)
+		return 0;
+
+	file = mock_file(i915);
+	if (IS_ERR(file))
+		return PTR_ERR(file);
+
+	mutex_lock(&i915->drm.struct_mutex);
+
+	ctx = kcalloc(nctx, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx) {
+		err = -ENOMEM;
+		goto out_unlock;
+	}
+
+	for (n = 0; n < nctx; n++) {
+		ctx[n] = i915_gem_create_context(i915, file->driver_priv);
+		if (IS_ERR(ctx[n])) {
+			err = PTR_ERR(ctx[n]);
+			goto out_unlock;
+		}
+	}
+
+	for_each_engine(engine, i915, id) {
+		struct i915_request *rq;
+		unsigned long end_time, prime;
+		ktime_t times[2] = {};
+
+		times[0] = ktime_get_raw();
+		for (n = 0; n < nctx; n++) {
+			rq = i915_request_alloc(engine, ctx[n]);
+			if (IS_ERR(rq)) {
+				err = PTR_ERR(rq);
+				goto out_unlock;
+			}
+			i915_request_add(rq);
+		}
+		i915_request_wait(rq,
+				  I915_WAIT_LOCKED,
+				  MAX_SCHEDULE_TIMEOUT);
+		times[1] = ktime_get_raw();
+
+		pr_info("Populated %d contexts on %s in %lluns\n",
+			nctx, engine->name, ktime_to_ns(times[1] - times[0]));
+
+		err = begin_live_test(&t, i915, __func__, engine->name);
+		if (err)
+			goto out_unlock;
+
+		end_time = jiffies + i915_selftest.timeout_jiffies;
+		for_each_prime_number_from(prime, 2, 8192) {
+			times[1] = ktime_get_raw();
+
+			for (n = 0; n < prime; n++) {
+				rq = i915_request_alloc(engine, ctx[n % nctx]);
+				if (IS_ERR(rq)) {
+					err = PTR_ERR(rq);
+					goto out_unlock;
+				}
+
+				/*
+				 * This space is left intentionally blank.
+				 *
+				 * We do not actually want to perform any
+				 * action with this request, we just want
+				 * to measure the latency in allocation
+				 * and submission of our breadcrumbs -
+				 * ensuring that the bare request is sufficient
+				 * for the system to work (i.e. proper HEAD
+				 * tracking of the rings, interrupt handling,
+				 * etc). It also gives us the lowest bounds
+				 * for latency.
+				 */
+
+				i915_request_add(rq);
+			}
+			i915_request_wait(rq,
+					  I915_WAIT_LOCKED,
+					  MAX_SCHEDULE_TIMEOUT);
+
+			times[1] = ktime_sub(ktime_get_raw(), times[1]);
+			if (prime == 2)
+				times[0] = times[1];
+
+			if (__igt_timeout(end_time, NULL))
+				break;
+		}
+
+		err = end_live_test(&t);
+		if (err)
+			goto out_unlock;
+
+		pr_info("Switch latencies on %s: 1 = %lluns, %lu = %lluns\n",
+			engine->name,
+			ktime_to_ns(times[0]),
+			prime - 1, div64_u64(ktime_to_ns(times[1]), prime - 1));
+	}
+
+out_unlock:
+	mutex_unlock(&i915->drm.struct_mutex);
+	mock_file_free(i915, file);
+	return err;
+}
+
 static struct i915_vma *
 gpu_fill_dw(struct i915_vma *vma, u64 offset, unsigned long count, u32 value)
 {
@@ -713,6 +900,7 @@ int i915_gem_context_live_selftests(struct drm_i915_private *dev_priv)
 {
 	static const struct i915_subtest tests[] = {
 		SUBTEST(igt_switch_to_kernel_context),
+		SUBTEST(live_nop_switch),
 		SUBTEST(igt_ctx_exec),
 		SUBTEST(igt_ctx_readonly),
 	};
-- 
2.19.0.rc2

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

  parent reply	other threads:[~2018-09-11 12:00 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-11 11:57 [PATCH 01/26] drm/i915/ringbuffer: Reload PDs harder on byt/bcs Chris Wilson
2018-09-11 11:57 ` [PATCH 02/26] drm/i915: Reorder execobject[] to insert non-48b objects into the low 4G Chris Wilson
2018-09-12  9:49   ` Joonas Lahtinen
2018-09-11 11:57 ` [PATCH 03/26] drm/i915: Limit number of capture objects Chris Wilson
2018-09-11 11:57 ` [PATCH 04/26] drm/i915: Handle incomplete Z_FINISH for compressed error states Chris Wilson
2018-09-11 11:57 ` [PATCH 05/26] drm/i915: Clear the error PTE just once on finish Chris Wilson
2018-09-11 11:57 ` [PATCH 06/26] drm/i915: Cache the error string Chris Wilson
2018-09-11 11:57 ` [PATCH 07/26] drm/i915/overlay: Allocate physical registers from stolen Chris Wilson
2018-09-11 11:57 ` [PATCH 08/26] drm/i915/overlay: Use the ioctl parameters directly Chris Wilson
2018-09-11 11:57 ` [PATCH 09/26] drm/i915/execlists: Reset CSB pointers on canceling requests (wedging) Chris Wilson
2018-09-11 11:57 ` [PATCH 10/26] drm/i915/execlists: Avoid kicking priority on the current context Chris Wilson
2018-09-11 11:57 ` Chris Wilson [this message]
2018-09-11 11:57 ` [PATCH 12/26] drm/i915/execlists: Delay updating ring register state after resume Chris Wilson
2018-09-11 11:57 ` [PATCH 13/26] drm/i915/execlists: Use coherent writes into the context image Chris Wilson
2018-09-11 11:57 ` [PATCH 14/26] drm/i915/execlists: Onion unwind for logical_ring_init() failure Chris Wilson
2018-09-11 11:57 ` [PATCH 15/26] drm/i915/execlists: Assert the queue is non-empty on unsubmitting Chris Wilson
2018-09-11 11:58 ` [PATCH 16/26] drm/i915: Report the number of closed vma held by each context in debugfs Chris Wilson
2018-09-11 11:58 ` [PATCH 17/26] drm/i915: Remove debugfs/i915_ppgtt_info Chris Wilson
2018-09-11 11:58 ` [PATCH 18/26] drm/i915: Track all held rpm wakerefs Chris Wilson
2018-09-11 11:58 ` [PATCH 19/26] drm/i915: Markup paired operations on wakerefs Chris Wilson
2018-09-11 11:58 ` [PATCH 20/26] drm/i915: Syntatic sugar for using intel_runtime_pm Chris Wilson
2018-09-11 11:58 ` [PATCH 21/26] drm/i915: Markup paired operations on display power domains Chris Wilson
2018-09-11 11:58 ` [PATCH 22/26] drm/i915: Track the wakeref used to initialise " Chris Wilson
2018-09-11 11:58 ` [PATCH 23/26] drm/i915/dp: Markup pps lock power well Chris Wilson
2018-09-11 11:58 ` [PATCH 24/26] drm/i915: Complain if hsw_get_pipe_config acquires the same power well twice Chris Wilson
2018-09-11 11:58 ` [PATCH 25/26] drm/i915: Mark up Ironlake ips with rpm wakerefs Chris Wilson
2018-09-11 11:58 ` [PATCH 26/26] drm/i915: Serialise concurrent calls to i915_gem_set_wedged() Chris Wilson
2018-09-11 13:50 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/26] drm/i915/ringbuffer: Reload PDs harder on byt/bcs Patchwork
2018-09-11 13:57 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-09-11 14:06 ` ✓ Fi.CI.BAT: success " Patchwork
2018-09-11 14:56 ` ✓ Fi.CI.IGT: " Patchwork
2018-09-12  9:44 ` [PATCH 01/26] " Joonas Lahtinen

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=20180911115810.8917-11-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.