diff mbox

[v2,14/38] drm/i915: Simple selftest to exercise live requests

Message ID 20170119114158.17941-15-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson Jan. 19, 2017, 11:41 a.m. UTC
Just create several batches of requests and expect it to not fall over!

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/selftests/i915_gem_request.c  | 95 ++++++++++++++++++++++
 .../gpu/drm/i915/selftests/i915_live_selftests.h   |  1 +
 2 files changed, 96 insertions(+)

Comments

Joonas Lahtinen Feb. 1, 2017, 8:14 a.m. UTC | #1
On to, 2017-01-19 at 11:41 +0000, Chris Wilson wrote:
> Just create several batches of requests and expect it to not fall over!
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

<SNIP>

> +static int live_nop_request(void *arg)
> +{

<SNIP>

> +		for_each_prime_number_from(prime, 1, 8192) {

#define MAGIC_PRIME_2 8192

> +			times[1] = ktime_get_raw();
> +
> +			for (n = 0; n < prime; n++) {
> +				request = i915_gem_request_alloc(engine,
> +								 i915->kernel_context);
> +				if (IS_ERR(request)) {
> +					err = PTR_ERR(request);
> +					goto out_unlock;
> +				}

Emitting even a single MI_NOOP or making a comment that the request
will contain instructions even if we do nothing here, might help a
newcomer.

> +
> +				i915_add_request(request);
> +			}
> +			i915_wait_request(request,
> +					  I915_WAIT_LOCKED,
> +					  MAX_SCHEDULE_TIMEOUT);
> +
> +			times[1] = ktime_sub(ktime_get_raw(), times[1]);
> +			if (prime == 1)
> +				times[0] = times[1];

Having this as an array is just hiding names and gaining nothing, how
about calling them just time_first, time_last?

Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

Regards, Joonas
Chris Wilson Feb. 1, 2017, 10:31 a.m. UTC | #2
On Wed, Feb 01, 2017 at 10:14:28AM +0200, Joonas Lahtinen wrote:
> On to, 2017-01-19 at 11:41 +0000, Chris Wilson wrote:
> > Just create several batches of requests and expect it to not fall over!
> > 
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> <SNIP>
> 
> > +static int live_nop_request(void *arg)
> > +{
> 
> <SNIP>
> 
> > +		for_each_prime_number_from(prime, 1, 8192) {
> 
> #define MAGIC_PRIME_2 8192

I'm sorry, but that is worse than having a very clear arbitrary number.

> > +
> > +				i915_add_request(request);
> > +			}
> > +			i915_wait_request(request,
> > +					  I915_WAIT_LOCKED,
> > +					  MAX_SCHEDULE_TIMEOUT);
> > +
> > +			times[1] = ktime_sub(ktime_get_raw(), times[1]);
> > +			if (prime == 1)
> > +				times[0] = times[1];
> 
> Having this as an array is just hiding names and gaining nothing, how
> about calling them just time_first, time_last?

time_0, time_N? The array is because I did/am considering that the graph
may be interesting. There should be a plateau at the point the ring is
full - not world shattering, just mildly interesting. Still, probably
want the times for cold submit_1 vs warm submit_1.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_request.c b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
index 20bf10dd85ed..19103d87a4c3 100644
--- a/drivers/gpu/drm/i915/selftests/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_gem_request.c
@@ -22,6 +22,8 @@ 
  *
  */
 
+#include <linux/prime_numbers.h>
+
 #include "i915_selftest.h"
 
 #include "mock_gem_device.h"
@@ -161,3 +163,96 @@  int i915_gem_request_mock_selftests(void)
 
 	return err;
 }
+
+static int live_nop_request(void *arg)
+{
+	struct drm_i915_private *i915 = arg;
+	struct intel_engine_cs *engine;
+	unsigned int id;
+	int err;
+
+	/* Submit various sized batches of empty requests, to each engine
+	 * (individually), and wait for the batch to complete. We can check
+	 * the overhead of submitting requests to the hardware.
+	 */
+
+	mutex_lock(&i915->drm.struct_mutex);
+
+	for_each_engine(engine, i915, id) {
+		IGT_TIMEOUT(end_time);
+		struct drm_i915_gem_request *request;
+		unsigned int reset_count;
+		unsigned long n, prime;
+		ktime_t times[2] = {};
+
+		err = i915_gem_wait_for_idle(i915, I915_WAIT_LOCKED);
+		if (err) {
+			pr_err("Failed to idle GPU before %s(%s)\n",
+			       __func__, engine->name);
+			goto out_unlock;
+		}
+
+		i915->gpu_error.missed_irq_rings = 0;
+		reset_count = i915_reset_count(&i915->gpu_error);
+
+		for_each_prime_number_from(prime, 1, 8192) {
+			times[1] = ktime_get_raw();
+
+			for (n = 0; n < prime; n++) {
+				request = i915_gem_request_alloc(engine,
+								 i915->kernel_context);
+				if (IS_ERR(request)) {
+					err = PTR_ERR(request);
+					goto out_unlock;
+				}
+
+				i915_add_request(request);
+			}
+			i915_wait_request(request,
+					  I915_WAIT_LOCKED,
+					  MAX_SCHEDULE_TIMEOUT);
+
+			times[1] = ktime_sub(ktime_get_raw(), times[1]);
+			if (prime == 1)
+				times[0] = times[1];
+
+			if (igt_timeout(end_time,
+					"%s(%s) timed out: last batch size %lu\n",
+					__func__, engine->name, prime))
+				break;
+		}
+
+		if (reset_count != i915_reset_count(&i915->gpu_error)) {
+			pr_err("%s(%s): GPU was reset %d times!\n",
+			       __func__, engine->name,
+			       i915_reset_count(&i915->gpu_error) - reset_count);
+			err = -EIO;
+			goto out_unlock;
+		}
+
+		if (i915->gpu_error.missed_irq_rings) {
+			pr_err("%s(%s): Missed interrupts on rings %lx\n",
+			       __func__, engine->name,
+			       i915->gpu_error.missed_irq_rings);
+			err = -EIO;
+			goto out_unlock;
+		}
+
+		pr_info("Request latencies on %s: 1 = %lluns, %lu = %lluns\n",
+			engine->name,
+			ktime_to_ns(times[0]),
+			prime, div64_u64(ktime_to_ns(times[1]), prime));
+	}
+
+out_unlock:
+	mutex_unlock(&i915->drm.struct_mutex);
+	return err;
+}
+
+int i915_gem_request_live_selftests(struct drm_i915_private *i915)
+{
+	static const struct i915_subtest tests[] = {
+		SUBTEST(live_nop_request),
+	};
+	return i915_subtests(tests, i915);
+}
diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
index f3e17cb10e05..09bf538826df 100644
--- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
+++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
@@ -9,3 +9,4 @@ 
  * Tests are executed in order by igt/drv_selftest
  */
 selftest(sanitycheck, i915_live_sanitycheck) /* keep first (igt selfcheck) */
+selftest(requests, i915_gem_request_live_selftests)