All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence
@ 2017-12-22 13:13 Tvrtko Ursulin
  2017-12-22 13:13 ` [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing Tvrtko Ursulin
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Tvrtko Ursulin @ 2017-12-22 13:13 UTC (permalink / raw)
  To: Intel-gfx

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

Support creating spin batches which return an output fence using new
__igt_spin_batch_new_fence / igt_spin_batch_new_fence API.

This will be used fromthe perf_pmu@interrupts test to ensure user
interrupt generation from a batch with controlled duration.

v2: Support out fence with multiple engines as well. (Chris Wilson)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
---
 lib/igt_dummyload.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++------
 lib/igt_dummyload.h | 10 +++++++
 2 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
index d19b4e5ea3d2..27eb402bb699 100644
--- a/lib/igt_dummyload.c
+++ b/lib/igt_dummyload.c
@@ -34,6 +34,7 @@
 #include "intel_chipset.h"
 #include "intel_reg.h"
 #include "ioctl_wrappers.h"
+#include "sw_sync.h"
 
 /**
  * SECTION:igt_dummyload
@@ -70,9 +71,9 @@ fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
 	reloc->write_domain = write_domains;
 }
 
-static void emit_recursive_batch(igt_spin_t *spin,
-				 int fd, uint32_t ctx, unsigned engine,
-				 uint32_t dep)
+static int emit_recursive_batch(igt_spin_t *spin,
+				int fd, uint32_t ctx, unsigned engine,
+				uint32_t dep, bool out_fence)
 {
 #define SCRATCH 0
 #define BATCH 1
@@ -82,6 +83,7 @@ static void emit_recursive_batch(igt_spin_t *spin,
 	struct drm_i915_gem_execbuffer2 execbuf;
 	unsigned int engines[16];
 	unsigned int nengine;
+	int fence_fd = -1;
 	uint32_t *batch;
 	int i;
 
@@ -165,22 +167,44 @@ static void emit_recursive_batch(igt_spin_t *spin,
 	execbuf.buffers_ptr = to_user_pointer(obj + (2 - execbuf.buffer_count));
 	execbuf.rsvd1 = ctx;
 
+	if (out_fence)
+		execbuf.flags |= I915_EXEC_FENCE_OUT;
+
 	for (i = 0; i < nengine; i++) {
 		execbuf.flags &= ~ENGINE_MASK;
-		execbuf.flags = engines[i];
-		gem_execbuf(fd, &execbuf);
+		execbuf.flags |= engines[i];
+		gem_execbuf_wr(fd, &execbuf);
+		if (out_fence) {
+			int _fd = execbuf.rsvd2 >> 32;
+
+			igt_assert(_fd >= 0);
+			if (fence_fd == -1) {
+				fence_fd = _fd;
+			} else {
+				int old_fd = fence_fd;
+
+				fence_fd = sync_fence_merge(old_fd, _fd);
+				close(old_fd);
+				close(_fd);
+			}
+			igt_assert(fence_fd >= 0);
+		}
 	}
+
+	return fence_fd;
 }
 
-igt_spin_t *
-__igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)
+static igt_spin_t *
+___igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep,
+		      int out_fence)
 {
 	igt_spin_t *spin;
 
 	spin = calloc(1, sizeof(struct igt_spin));
 	igt_assert(spin);
 
-	emit_recursive_batch(spin, fd, ctx, engine, dep);
+	spin->out_fence = emit_recursive_batch(spin, fd, ctx, engine, dep,
+					       out_fence);
 	igt_assert(gem_bo_busy(fd, spin->handle));
 
 	pthread_mutex_lock(&list_lock);
@@ -190,6 +214,12 @@ __igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)
 	return spin;
 }
 
+igt_spin_t *
+__igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)
+{
+	return ___igt_spin_batch_new(fd, ctx, engine, dep, false);
+}
+
 /**
  * igt_spin_batch_new:
  * @fd: open i915 drm file descriptor
@@ -213,6 +243,36 @@ igt_spin_batch_new(int fd, uint32_t ctx, unsigned engine, uint32_t dep)
 	return __igt_spin_batch_new(fd, ctx, engine, dep);
 }
 
+igt_spin_t *
+__igt_spin_batch_new_fence(int fd, uint32_t ctx, unsigned engine)
+{
+	return ___igt_spin_batch_new(fd, ctx, engine, 0, true);
+}
+
+/**
+ * igt_spin_batch_new_fence:
+ * @fd: open i915 drm file descriptor
+ * @engine: Ring to execute batch OR'd with execbuf flags. If value is less
+ *          than 0, execute on all available rings.
+ *
+ * Start a recursive batch on a ring. Immediately returns a #igt_spin_t that
+ * contains the batch's handle that can be waited upon. The returned structure
+ * must be passed to igt_spin_batch_free() for post-processing.
+ *
+ * igt_spin_t will contain an output fence associtated with this batch.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_spin_batch_free().
+ */
+igt_spin_t *
+igt_spin_batch_new_fence(int fd, uint32_t ctx, unsigned engine)
+{
+	igt_require_gem(fd);
+	igt_require(gem_has_exec_fence(fd));
+
+	return __igt_spin_batch_new_fence(fd, ctx, engine);
+}
+
 static void notify(union sigval arg)
 {
 	igt_spin_t *spin = arg.sival_ptr;
@@ -295,6 +355,10 @@ void igt_spin_batch_free(int fd, igt_spin_t *spin)
 	gem_munmap(spin->batch, BATCH_SIZE);
 
 	gem_close(fd, spin->handle);
+
+	if (spin->out_fence >= 0)
+		close(spin->out_fence);
+
 	free(spin);
 }
 
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
index 215425f7c6c0..ffa7e351dea3 100644
--- a/lib/igt_dummyload.h
+++ b/lib/igt_dummyload.h
@@ -35,6 +35,7 @@ typedef struct igt_spin {
 	timer_t timer;
 	struct igt_list link;
 	uint32_t *batch;
+	int out_fence;
 } igt_spin_t;
 
 igt_spin_t *__igt_spin_batch_new(int fd,
@@ -45,6 +46,15 @@ igt_spin_t *igt_spin_batch_new(int fd,
 			       uint32_t ctx,
 			       unsigned engine,
 			       uint32_t  dep);
+
+igt_spin_t *__igt_spin_batch_new_fence(int fd,
+				       uint32_t ctx,
+				       unsigned engine);
+
+igt_spin_t *igt_spin_batch_new_fence(int fd,
+				     uint32_t ctx,
+				     unsigned engine);
+
 void igt_spin_batch_set_timeout(igt_spin_t *spin, int64_t ns);
 void igt_spin_batch_end(igt_spin_t *spin);
 void igt_spin_batch_free(int fd, igt_spin_t *spin);
-- 
2.14.1

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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing
  2017-12-22 13:13 [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence Tvrtko Ursulin
@ 2017-12-22 13:13 ` Tvrtko Ursulin
  2017-12-22 13:51   ` Chris Wilson
  2017-12-22 13:36 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] lib/dummyload: Support returning output fence Patchwork
  2017-12-22 13:47 ` [PATCH i-g-t 1/2] " Chris Wilson
  2 siblings, 1 reply; 5+ messages in thread
From: Tvrtko Ursulin @ 2017-12-22 13:13 UTC (permalink / raw)
  To: Intel-gfx

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

Rather than calibrate and emit nop batches, use a manually signalled chain
of spinners to generate the desired interrupts.

v2: Two flavours of interrupt generation. (Chris Wilson)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 tests/perf_pmu.c | 141 +++++++++++++++++++++++++++----------------------------
 1 file changed, 69 insertions(+), 72 deletions(-)

diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
index db7696115a7b..54707dea63af 100644
--- a/tests/perf_pmu.c
+++ b/tests/perf_pmu.c
@@ -799,94 +799,85 @@ static void cpu_hotplug(int gem_fd)
 	assert_within_epsilon(val, ref, tolerance);
 }
 
-static unsigned long calibrate_nop(int fd, const uint64_t calibration_us)
+static void
+test_interrupts(int gem_fd)
 {
-	const uint64_t cal_min_us = calibration_us * 3;
-	const unsigned int tolerance_pct = 10;
-	const uint32_t bbe = MI_BATCH_BUFFER_END;
-	const unsigned int loops = 17;
-	struct drm_i915_gem_exec_object2 obj = {};
-	struct drm_i915_gem_execbuffer2 eb = {
-		.buffer_count = 1, .buffers_ptr = to_user_pointer(&obj),
-	};
-	struct timespec t_begin = { };
-	uint64_t size, last_size, ns;
-
-	igt_nsec_elapsed(&t_begin);
-
-	size = 256 * 1024;
-	do {
-		struct timespec t_start = { };
+	const unsigned int test_duration_ms = 1000;
+	const int target = 30;
+	igt_spin_t *spin[target];
+	struct pollfd pfd;
+	uint64_t idle, busy;
+	int fence_fd;
+	int fd;
 
-		obj.handle = gem_create(fd, size);
-		gem_write(fd, obj.handle, size - sizeof(bbe), &bbe,
-			  sizeof(bbe));
-		gem_execbuf(fd, &eb);
-		gem_sync(fd, obj.handle);
+	gem_quiescent_gpu(gem_fd);
 
-		igt_nsec_elapsed(&t_start);
+	fd = open_pmu(I915_PMU_INTERRUPTS);
 
-		for (int loop = 0; loop < loops; loop++)
-			gem_execbuf(fd, &eb);
-		gem_sync(fd, obj.handle);
+	/* Queue spinning batches. */
+	for (int i = 0; i < target; i++) {
+		spin[i] = igt_spin_batch_new_fence(gem_fd, 0, I915_EXEC_RENDER);
+		if (i == 0) {
+			fence_fd = spin[i]->out_fence;
+		} else {
+			int old_fd = fence_fd;
 
-		ns = igt_nsec_elapsed(&t_start);
+			fence_fd = sync_fence_merge(old_fd,
+						    spin[i]->out_fence);
+			close(old_fd);
+		}
 
-		gem_close(fd, obj.handle);
+		igt_assert(fence_fd >= 0);
+	}
+
+	/* Wait for idle state. */
+	idle = pmu_read_single(fd);
+	do {
+		busy = idle;
+		usleep(1e3);
+		idle = pmu_read_single(fd);
+	} while (idle != busy);
 
-		last_size = size;
-		size = calibration_us * 1000 * size * loops / ns;
-		size = ALIGN(size, sizeof(uint32_t));
-	} while (igt_nsec_elapsed(&t_begin) / 1000 < cal_min_us ||
-		 abs(size - last_size) > (size * tolerance_pct / 100));
+	/* Arm batch expiration. */
+	for (int i = 0; i < target; i++)
+		igt_spin_batch_set_timeout(spin[i],
+					   (i + 1) * test_duration_ms * 1e6
+					   / target);
+
+	/* Wait for last batch to finish. */
+	pfd.events = POLLIN;
+	pfd.fd = fence_fd;
+	igt_assert_eq(poll(&pfd, 1, 2 * test_duration_ms), 1);
+	close(fence_fd);
 
-	return size;
+	/* Free batches. */
+	for (int i = 0; i < target; i++)
+		igt_spin_batch_free(gem_fd, spin[i]);
+
+	/* Check at least as many interrupts has been generated. */
+	busy = pmu_read_single(fd) - idle;
+	close(fd);
+
+	igt_assert_lte(target, busy);
 }
 
 static void
-test_interrupts(int gem_fd)
+test_interrupts_sync(int gem_fd)
 {
-	const uint32_t bbe = MI_BATCH_BUFFER_END;
 	const unsigned int test_duration_ms = 1000;
-	struct drm_i915_gem_exec_object2 obj = { };
-	struct drm_i915_gem_execbuffer2 eb = {
-		.buffers_ptr = to_user_pointer(&obj),
-		.buffer_count = 1,
-		.flags = I915_EXEC_FENCE_OUT,
-	};
-	unsigned long sz;
-	igt_spin_t *spin;
 	const int target = 30;
+	igt_spin_t *spin[target];
 	struct pollfd pfd;
 	uint64_t idle, busy;
 	int fd;
 
-	sz = calibrate_nop(gem_fd, test_duration_ms * 1000 / target);
 	gem_quiescent_gpu(gem_fd);
 
 	fd = open_pmu(I915_PMU_INTERRUPTS);
-	spin = igt_spin_batch_new(gem_fd, 0, 0, 0);
-
-	obj.handle = gem_create(gem_fd, sz);
-	gem_write(gem_fd, obj.handle, sz - sizeof(bbe), &bbe, sizeof(bbe));
-
-	pfd.events = POLLIN;
-	pfd.fd = -1;
-	for (int i = 0; i < target; i++) {
-		int new;
 
-		/* Merge all the fences together so we can wait on them all */
-		gem_execbuf_wr(gem_fd, &eb);
-		new = eb.rsvd2 >> 32;
-		if (pfd.fd == -1) {
-			pfd.fd = new;
-		} else {
-			int old = pfd.fd;
-			pfd.fd = sync_fence_merge(old, new);
-			close(old);
-			close(new);
-		}
-	}
+	/* Queue spinning batches. */
+	for (int i = 0; i < target; i++)
+		spin[i] = __igt_spin_batch_new_fence(gem_fd, 0, 0);
 
 	/* Wait for idle state. */
 	idle = pmu_read_single(fd);
@@ -896,13 +887,16 @@ test_interrupts(int gem_fd)
 		idle = pmu_read_single(fd);
 	} while (idle != busy);
 
-	/* Install the fences and enable signaling */
-	igt_assert_eq(poll(&pfd, 1, 10), 0);
+	/* Process the batch queue. */
+	pfd.events = POLLIN;
+	for (int i = 0; i < target; i++) {
+		const unsigned int timeout_ms = test_duration_ms / target;
 
-	/* Unplug the calibrated queue and wait for all the fences */
-	igt_spin_batch_free(gem_fd, spin);
-	igt_assert_eq(poll(&pfd, 1, 2 * test_duration_ms), 1);
-	close(pfd.fd);
+		pfd.fd = spin[i]->out_fence;
+		igt_spin_batch_set_timeout(spin[i], timeout_ms * 1e6);
+		igt_assert_eq(poll(&pfd, 1, 2 * timeout_ms), 1);
+		igt_spin_batch_free(gem_fd, spin[i]);
+	}
 
 	/* Check at least as many interrupts has been generated. */
 	busy = pmu_read_single(fd) - idle;
@@ -1184,6 +1178,9 @@ igt_main
 	igt_subtest("interrupts")
 		test_interrupts(fd);
 
+	igt_subtest("interrupts-sync")
+		test_interrupts_sync(fd);
+
 	/**
 	 * Test RC6 residency reporting.
 	 */
-- 
2.14.1

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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* ✗ Fi.CI.BAT: failure for series starting with [1/2] lib/dummyload: Support returning output fence
  2017-12-22 13:13 [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence Tvrtko Ursulin
  2017-12-22 13:13 ` [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing Tvrtko Ursulin
@ 2017-12-22 13:36 ` Patchwork
  2017-12-22 13:47 ` [PATCH i-g-t 1/2] " Chris Wilson
  2 siblings, 0 replies; 5+ messages in thread
From: Patchwork @ 2017-12-22 13:36 UTC (permalink / raw)
  To: Tvrtko Ursulin; +Cc: intel-gfx

== Series Details ==

Series: series starting with [1/2] lib/dummyload: Support returning output fence
URL   : https://patchwork.freedesktop.org/series/35718/
State : failure

== Summary ==

IGT patchset tested on top of latest successful build
865a47ca2b93b208ba016f3c4fc00831ec7bfec6 overlay: parse tracepoints from sysfs to figure out fields' location

with latest DRM-Tip kernel build CI_DRM_3569
34783c4253df drm-tip: 2017y-12m-22d-12h-46m-57s UTC integration manifest

Testlist changes:
+igt@perf_pmu@interrupts-sync

Test debugfs_test:
        Subgroup read_all_entries:
                dmesg-warn -> DMESG-FAIL (fi-elk-e7500) fdo#103989
Test kms_flip:
        Subgroup basic-flip-vs-wf_vblank:
                pass       -> FAIL       (fi-snb-2520m)
Test kms_pipe_crc_basic:
        Subgroup suspend-read-crc-pipe-b:
                pass       -> INCOMPLETE (fi-snb-2520m) fdo#103713
Test kms_psr_sink_crc:
        Subgroup psr_basic:
                pass       -> DMESG-WARN (fi-skl-6700hq) fdo#101144

fdo#103989 https://bugs.freedesktop.org/show_bug.cgi?id=103989
fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713
fdo#101144 https://bugs.freedesktop.org/show_bug.cgi?id=101144

fi-bdw-5557u     total:288  pass:267  dwarn:0   dfail:0   fail:0   skip:21  time:436s
fi-bdw-gvtdvm    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:443s
fi-blb-e6850     total:288  pass:223  dwarn:1   dfail:0   fail:0   skip:64  time:386s
fi-bsw-n3050     total:288  pass:242  dwarn:0   dfail:0   fail:0   skip:46  time:494s
fi-bwr-2160      total:288  pass:183  dwarn:0   dfail:0   fail:0   skip:105 time:277s
fi-bxt-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:492s
fi-bxt-j4205     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:504s
fi-byt-j1900     total:288  pass:253  dwarn:0   dfail:0   fail:0   skip:35  time:480s
fi-byt-n2820     total:288  pass:249  dwarn:0   dfail:0   fail:0   skip:39  time:468s
fi-elk-e7500     total:224  pass:163  dwarn:14  dfail:1   fail:0   skip:45 
fi-gdg-551       total:288  pass:179  dwarn:0   dfail:0   fail:1   skip:108 time:262s
fi-glk-1         total:288  pass:260  dwarn:0   dfail:0   fail:0   skip:28  time:530s
fi-hsw-4770      total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:410s
fi-hsw-4770r     total:288  pass:261  dwarn:0   dfail:0   fail:0   skip:27  time:413s
fi-ilk-650       total:288  pass:228  dwarn:0   dfail:0   fail:0   skip:60  time:425s
fi-ivb-3520m     total:288  pass:259  dwarn:0   dfail:0   fail:0   skip:29  time:481s
fi-ivb-3770      total:288  pass:255  dwarn:0   dfail:0   fail:0   skip:33  time:427s
fi-kbl-7500u     total:288  pass:263  dwarn:1   dfail:0   fail:0   skip:24  time:478s
fi-kbl-7560u     total:288  pass:268  dwarn:1   dfail:0   fail:0   skip:19  time:523s
fi-kbl-7567u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:467s
fi-kbl-r         total:288  pass:260  dwarn:1   dfail:0   fail:0   skip:27  time:521s
fi-pnv-d510      total:288  pass:222  dwarn:1   dfail:0   fail:0   skip:65  time:599s
fi-skl-6260u     total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:449s
fi-skl-6600u     total:288  pass:260  dwarn:1   dfail:0   fail:0   skip:27  time:532s
fi-skl-6700hq    total:288  pass:261  dwarn:1   dfail:0   fail:0   skip:26  time:557s
fi-skl-6700k2    total:288  pass:264  dwarn:0   dfail:0   fail:0   skip:24  time:510s
fi-skl-6770hq    total:288  pass:268  dwarn:0   dfail:0   fail:0   skip:20  time:498s
fi-skl-gvtdvm    total:288  pass:265  dwarn:0   dfail:0   fail:0   skip:23  time:447s
fi-snb-2520m     total:245  pass:210  dwarn:0   dfail:0   fail:1   skip:33 
fi-snb-2600      total:288  pass:248  dwarn:0   dfail:0   fail:0   skip:40  time:410s
Blacklisted hosts:
fi-cfl-s2        total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:596s
fi-cnl-y         total:288  pass:262  dwarn:0   dfail:0   fail:0   skip:26  time:615s
fi-glk-dsi       total:288  pass:258  dwarn:0   dfail:0   fail:0   skip:30  time:483s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_726/issues.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence
  2017-12-22 13:13 [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence Tvrtko Ursulin
  2017-12-22 13:13 ` [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing Tvrtko Ursulin
  2017-12-22 13:36 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] lib/dummyload: Support returning output fence Patchwork
@ 2017-12-22 13:47 ` Chris Wilson
  2 siblings, 0 replies; 5+ messages in thread
From: Chris Wilson @ 2017-12-22 13:47 UTC (permalink / raw)
  To: Tvrtko Ursulin, Intel-gfx

Quoting Tvrtko Ursulin (2017-12-22 13:13:47)
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Support creating spin batches which return an output fence using new
> __igt_spin_batch_new_fence / igt_spin_batch_new_fence API.
> 
> This will be used fromthe perf_pmu@interrupts test to ensure user
> interrupt generation from a batch with controlled duration.
> 
> v2: Support out fence with multiple engines as well. (Chris Wilson)
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v1)
> ---
>  lib/igt_dummyload.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++------
>  lib/igt_dummyload.h | 10 +++++++
>  2 files changed, 82 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/igt_dummyload.c b/lib/igt_dummyload.c
> index d19b4e5ea3d2..27eb402bb699 100644
> --- a/lib/igt_dummyload.c
> +++ b/lib/igt_dummyload.c
> @@ -34,6 +34,7 @@
>  #include "intel_chipset.h"
>  #include "intel_reg.h"
>  #include "ioctl_wrappers.h"
> +#include "sw_sync.h"
>  
>  /**
>   * SECTION:igt_dummyload
> @@ -70,9 +71,9 @@ fill_reloc(struct drm_i915_gem_relocation_entry *reloc,
>         reloc->write_domain = write_domains;
>  }
>  
> -static void emit_recursive_batch(igt_spin_t *spin,
> -                                int fd, uint32_t ctx, unsigned engine,
> -                                uint32_t dep)
> +static int emit_recursive_batch(igt_spin_t *spin,
> +                               int fd, uint32_t ctx, unsigned engine,
> +                               uint32_t dep, bool out_fence)
>  {
>  #define SCRATCH 0
>  #define BATCH 1
> @@ -82,6 +83,7 @@ static void emit_recursive_batch(igt_spin_t *spin,
>         struct drm_i915_gem_execbuffer2 execbuf;
>         unsigned int engines[16];
>         unsigned int nengine;
> +       int fence_fd = -1;
>         uint32_t *batch;
>         int i;
>  
> @@ -165,22 +167,44 @@ static void emit_recursive_batch(igt_spin_t *spin,
>         execbuf.buffers_ptr = to_user_pointer(obj + (2 - execbuf.buffer_count));
>         execbuf.rsvd1 = ctx;
>  
> +       if (out_fence)
> +               execbuf.flags |= I915_EXEC_FENCE_OUT;
> +
>         for (i = 0; i < nengine; i++) {
>                 execbuf.flags &= ~ENGINE_MASK;
> -               execbuf.flags = engines[i];
> -               gem_execbuf(fd, &execbuf);
> +               execbuf.flags |= engines[i];
> +               gem_execbuf_wr(fd, &execbuf);
> +               if (out_fence) {
> +                       int _fd = execbuf.rsvd2 >> 32;
> +
> +                       igt_assert(_fd >= 0);
> +                       if (fence_fd == -1) {
> +                               fence_fd = _fd;
> +                       } else {
> +                               int old_fd = fence_fd;
> +
> +                               fence_fd = sync_fence_merge(old_fd, _fd);
> +                               close(old_fd);
> +                               close(_fd);
> +                       }
> +                       igt_assert(fence_fd >= 0);

At some point we will write sync_fence_accumulate that does all of the
above: fence_fd = sync_fence_accumulate(fence_fd, _fd);.

Looks correct, the only thing I would nitpick is spin->out_fence; at
that point it is just the fence representing the spinner, and
spin->fence is descriptive and accurate.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing
  2017-12-22 13:13 ` [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing Tvrtko Ursulin
@ 2017-12-22 13:51   ` Chris Wilson
  0 siblings, 0 replies; 5+ messages in thread
From: Chris Wilson @ 2017-12-22 13:51 UTC (permalink / raw)
  To: Tvrtko Ursulin, Intel-gfx

Quoting Tvrtko Ursulin (2017-12-22 13:13:48)
> From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> 
> Rather than calibrate and emit nop batches, use a manually signalled chain
> of spinners to generate the desired interrupts.
> 
> v2: Two flavours of interrupt generation. (Chris Wilson)
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  tests/perf_pmu.c | 141 +++++++++++++++++++++++++++----------------------------
>  1 file changed, 69 insertions(+), 72 deletions(-)
> 
> diff --git a/tests/perf_pmu.c b/tests/perf_pmu.c
> index db7696115a7b..54707dea63af 100644
> --- a/tests/perf_pmu.c
> +++ b/tests/perf_pmu.c
> @@ -799,94 +799,85 @@ static void cpu_hotplug(int gem_fd)
>         assert_within_epsilon(val, ref, tolerance);
>  }
>  
> -static unsigned long calibrate_nop(int fd, const uint64_t calibration_us)
> +static void
> +test_interrupts(int gem_fd)
>  {
> -       const uint64_t cal_min_us = calibration_us * 3;
> -       const unsigned int tolerance_pct = 10;
> -       const uint32_t bbe = MI_BATCH_BUFFER_END;
> -       const unsigned int loops = 17;
> -       struct drm_i915_gem_exec_object2 obj = {};
> -       struct drm_i915_gem_execbuffer2 eb = {
> -               .buffer_count = 1, .buffers_ptr = to_user_pointer(&obj),
> -       };
> -       struct timespec t_begin = { };
> -       uint64_t size, last_size, ns;
> -
> -       igt_nsec_elapsed(&t_begin);
> -
> -       size = 256 * 1024;
> -       do {
> -               struct timespec t_start = { };
> +       const unsigned int test_duration_ms = 1000;
> +       const int target = 30;
> +       igt_spin_t *spin[target];
> +       struct pollfd pfd;
> +       uint64_t idle, busy;
> +       int fence_fd;
> +       int fd;
>  
> -               obj.handle = gem_create(fd, size);
> -               gem_write(fd, obj.handle, size - sizeof(bbe), &bbe,
> -                         sizeof(bbe));
> -               gem_execbuf(fd, &eb);
> -               gem_sync(fd, obj.handle);
> +       gem_quiescent_gpu(gem_fd);
>  
> -               igt_nsec_elapsed(&t_start);
> +       fd = open_pmu(I915_PMU_INTERRUPTS);
>  
> -               for (int loop = 0; loop < loops; loop++)
> -                       gem_execbuf(fd, &eb);
> -               gem_sync(fd, obj.handle);
> +       /* Queue spinning batches. */
> +       for (int i = 0; i < target; i++) {
> +               spin[i] = igt_spin_batch_new_fence(gem_fd, 0, I915_EXEC_RENDER);
> +               if (i == 0) {
> +                       fence_fd = spin[i]->out_fence;
> +               } else {
> +                       int old_fd = fence_fd;
>  
> -               ns = igt_nsec_elapsed(&t_start);
> +                       fence_fd = sync_fence_merge(old_fd,
> +                                                   spin[i]->out_fence);
> +                       close(old_fd);
> +               }
>  
> -               gem_close(fd, obj.handle);
> +               igt_assert(fence_fd >= 0);
> +       }
> +
> +       /* Wait for idle state. */
> +       idle = pmu_read_single(fd);
> +       do {
> +               busy = idle;
> +               usleep(1e3);
> +               idle = pmu_read_single(fd);
> +       } while (idle != busy);
>  
> -               last_size = size;
> -               size = calibration_us * 1000 * size * loops / ns;
> -               size = ALIGN(size, sizeof(uint32_t));
> -       } while (igt_nsec_elapsed(&t_begin) / 1000 < cal_min_us ||
> -                abs(size - last_size) > (size * tolerance_pct / 100));
> +       /* Arm batch expiration. */
> +       for (int i = 0; i < target; i++)

Joonas would point out the benefit of using a local to get around col80.

> +               igt_spin_batch_set_timeout(spin[i],
> +                                          (i + 1) * test_duration_ms * 1e6
> +                                          / target);
> +
> +       /* Wait for last batch to finish. */
> +       pfd.events = POLLIN;
> +       pfd.fd = fence_fd;
> +       igt_assert_eq(poll(&pfd, 1, 2 * test_duration_ms), 1);
> +       close(fence_fd);
>  
> -       return size;
> +       /* Free batches. */
> +       for (int i = 0; i < target; i++)
> +               igt_spin_batch_free(gem_fd, spin[i]);
> +
> +       /* Check at least as many interrupts has been generated. */
> +       busy = pmu_read_single(fd) - idle;
> +       close(fd);
> +
> +       igt_assert_lte(target, busy);

Looks good.

>  }
>  
>  static void
> -test_interrupts(int gem_fd)
> +test_interrupts_sync(int gem_fd)
>  {
> -       const uint32_t bbe = MI_BATCH_BUFFER_END;
>         const unsigned int test_duration_ms = 1000;
> -       struct drm_i915_gem_exec_object2 obj = { };
> -       struct drm_i915_gem_execbuffer2 eb = {
> -               .buffers_ptr = to_user_pointer(&obj),
> -               .buffer_count = 1,
> -               .flags = I915_EXEC_FENCE_OUT,
> -       };
> -       unsigned long sz;
> -       igt_spin_t *spin;
>         const int target = 30;
> +       igt_spin_t *spin[target];
>         struct pollfd pfd;
>         uint64_t idle, busy;
>         int fd;
>  
> -       sz = calibrate_nop(gem_fd, test_duration_ms * 1000 / target);
>         gem_quiescent_gpu(gem_fd);
>  
>         fd = open_pmu(I915_PMU_INTERRUPTS);
> -       spin = igt_spin_batch_new(gem_fd, 0, 0, 0);
> -
> -       obj.handle = gem_create(gem_fd, sz);
> -       gem_write(gem_fd, obj.handle, sz - sizeof(bbe), &bbe, sizeof(bbe));
> -
> -       pfd.events = POLLIN;
> -       pfd.fd = -1;
> -       for (int i = 0; i < target; i++) {
> -               int new;
>  
> -               /* Merge all the fences together so we can wait on them all */
> -               gem_execbuf_wr(gem_fd, &eb);
> -               new = eb.rsvd2 >> 32;
> -               if (pfd.fd == -1) {
> -                       pfd.fd = new;
> -               } else {
> -                       int old = pfd.fd;
> -                       pfd.fd = sync_fence_merge(old, new);
> -                       close(old);
> -                       close(new);
> -               }
> -       }
> +       /* Queue spinning batches. */
> +       for (int i = 0; i < target; i++)
> +               spin[i] = __igt_spin_batch_new_fence(gem_fd, 0, 0);
>  
>         /* Wait for idle state. */
>         idle = pmu_read_single(fd);
> @@ -896,13 +887,16 @@ test_interrupts(int gem_fd)
>                 idle = pmu_read_single(fd);
>         } while (idle != busy);
>  
> -       /* Install the fences and enable signaling */
> -       igt_assert_eq(poll(&pfd, 1, 10), 0);
> +       /* Process the batch queue. */
> +       pfd.events = POLLIN;
> +       for (int i = 0; i < target; i++) {
> +               const unsigned int timeout_ms = test_duration_ms / target;
>  
> -       /* Unplug the calibrated queue and wait for all the fences */
> -       igt_spin_batch_free(gem_fd, spin);
> -       igt_assert_eq(poll(&pfd, 1, 2 * test_duration_ms), 1);
> -       close(pfd.fd);
> +               pfd.fd = spin[i]->out_fence;
> +               igt_spin_batch_set_timeout(spin[i], timeout_ms * 1e6);
> +               igt_assert_eq(poll(&pfd, 1, 2 * timeout_ms), 1);

(Going outside the purpose of this test, but I was thinking

igt_assert_eq(poll(&pfd, 1, timeout_ms), 0);
igt_spin_batch_end(gem_fd, spin[i]);
igt_assert_eq(poll(&pfd, 1, timeout_ms), 1);

would be fun and a bit different.)

> +               igt_spin_batch_free(gem_fd, spin[i]);
> +       }
>  
>         /* Check at least as many interrupts has been generated. */
>         busy = pmu_read_single(fd) - idle;
> @@ -1184,6 +1178,9 @@ igt_main
>         igt_subtest("interrupts")
>                 test_interrupts(fd);
>  
> +       igt_subtest("interrupts-sync")
> +               test_interrupts_sync(fd);
> +
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-12-22 13:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-22 13:13 [PATCH i-g-t 1/2] lib/dummyload: Support returning output fence Tvrtko Ursulin
2017-12-22 13:13 ` [PATCH i-g-t 2/2] tests/perf_pmu: Simplify interrupt testing Tvrtko Ursulin
2017-12-22 13:51   ` Chris Wilson
2017-12-22 13:36 ` ✗ Fi.CI.BAT: failure for series starting with [1/2] lib/dummyload: Support returning output fence Patchwork
2017-12-22 13:47 ` [PATCH i-g-t 1/2] " Chris Wilson

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.