Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Andrzej Hajda <andrzej.hajda@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Chris Wilson <chris.p.wilson@intel.com>,
	Chris Wilson <chris.p.wilson@linux.intel.com>,
	Nirmoy Das <nirmoy.das@intel.com>
Subject: [igt-dev] [PATCH i-g-t] i915/gem_exec_await: Avoid DG2 conflicts
Date: Thu,  6 Jul 2023 18:00:14 +0200	[thread overview]
Message-ID: <20230706160014.1027512-1-andrzej.hajda@intel.com> (raw)

From: Chris Wilson <chris.p.wilson@linux.intel.com>

DG2 is restricted in what contexts/engines can be run concurrently, if
we submit a non-preemptible context on both rcs/ccs it will only run one
at a time. Progress (heartbeats) along ccs will be blocked by rcs, and
vice versa. This is independent of the ccs switch holdout w/a.
Since this is not required for constructing a wide set of active fences
(a fence is active until it has been signaled, whether it is running on
HW or waiting to run is irrelevant to the signal state), refactor the
context construction to be favourable for DG2.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5892
Signed-off-by: Chris Wilson <chris.p.wilson@linux.intel.com>
[ahajda: adjust to upstream driver]
Signed-off-by: Andrzej Hajda <andrzej.hajda@intel.com>
---
 tests/i915/gem_exec_await.c | 180 ++++++++++++++++--------------------
 1 file changed, 80 insertions(+), 100 deletions(-)

diff --git a/tests/i915/gem_exec_await.c b/tests/i915/gem_exec_await.c
index 53b7bac2f96..b87adcb4a18 100644
--- a/tests/i915/gem_exec_await.c
+++ b/tests/i915/gem_exec_await.c
@@ -25,12 +25,23 @@
 #include <sys/ioctl.h>
 #include <sys/signal.h>
 
+#include "drmtest.h"
 #include "i915/gem.h"
 #include "i915/gem_create.h"
-#include "igt.h"
+#include "i915/gem_engine_topology.h"
+#include "i915/gem_mman.h"
+#include "i915/gem_submission.h"
+#include "i915/gem_vm.h"
+#include "igt_aux.h"
+#include "igt_core.h"
 #include "igt_rand.h"
 #include "igt_sysfs.h"
+#include "igt_types.h"
 #include "igt_vgem.h"
+#include "ioctl_wrappers.h"
+#include "intel_chipset.h"
+#include "intel_ctx.h"
+#include "intel_gpu_commands.h"
 /**
  * TEST: gem exec await
  * Category: Infrastructure
@@ -66,7 +77,7 @@ static void xchg_obj(void *array, unsigned i, unsigned j)
 }
 
 #define CONTEXTS 0x1
-static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
+static void wide(int fd, intel_ctx_cfg_t *cfg, int ring_size,
 		 int timeout, unsigned int flags)
 {
 	const struct intel_execution_engine2 *engine;
@@ -75,7 +86,6 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 	struct {
 		struct drm_i915_gem_exec_object2 *obj;
 		struct drm_i915_gem_exec_object2 exec[2];
-		struct drm_i915_gem_relocation_entry reloc;
 		struct drm_i915_gem_execbuffer2 execbuf;
 		const intel_ctx_t *ctx;
 		uint32_t *cmd;
@@ -83,9 +93,13 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 	struct drm_i915_gem_exec_object2 *obj;
 	struct drm_i915_gem_execbuffer2 execbuf;
 	unsigned engines[I915_EXEC_RING_MASK + 1], nengine;
+	const intel_ctx_t *ctx;
 	unsigned long count;
 	double time;
-	uint64_t ahnd = get_reloc_ahnd(fd, 0); /* just offset provider */
+
+	__gem_vm_create(fd, &cfg->vm);
+	if (__intel_ctx_create(fd, cfg, &ctx))
+		ctx = intel_ctx_0(fd);
 
 	nengine = 0;
 	for_each_ctx_engine(fd, ctx, engine) {
@@ -102,7 +116,7 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 	igt_assert(exec);
 
 	igt_require_memory(nengine*(2 + ring_size), 4096, CHECK_RAM);
-	obj = calloc(nengine*ring_size + 1, sizeof(*obj));
+	obj = calloc(nengine * (ring_size  + 1) + 1, sizeof(*obj));
 	igt_assert(obj);
 
 	for (unsigned e = 0; e < nengine; e++) {
@@ -111,69 +125,63 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 		for (unsigned n = 0; n < ring_size; n++)  {
 			exec[e].obj[n].handle = gem_create(fd, 4096);
 			exec[e].obj[n].flags = EXEC_OBJECT_WRITE;
-			exec[e].obj[n].offset = get_offset(ahnd, exec[e].obj[n].handle,
-							   4096, 0);
-			if (ahnd)
-				exec[e].obj[n].flags |= EXEC_OBJECT_PINNED;
-
-			obj[e*ring_size + n].handle = exec[e].obj[n].handle;
-			obj[e*ring_size + n].offset = exec[e].obj[n].offset;
+			obj[e * ring_size + n] = exec[e].obj[n];
 		}
 
 		exec[e].execbuf.buffers_ptr = to_user_pointer(exec[e].exec);
-		exec[e].execbuf.buffer_count = 1;
-		exec[e].execbuf.flags = (engines[e] |
-					 I915_EXEC_NO_RELOC |
-					 I915_EXEC_HANDLE_LUT);
+		exec[e].execbuf.buffer_count = 2;
+		exec[e].execbuf.flags = engines[e];
+		exec[e].execbuf.rsvd1 = ctx->id;
 
 		if (flags & CONTEXTS) {
-			exec[e].ctx = intel_ctx_create(fd, &ctx->cfg);
+			exec[e].ctx = intel_ctx_create(fd, cfg);
 			exec[e].execbuf.rsvd1 = exec[e].ctx->id;
-		} else {
-			exec[e].execbuf.rsvd1 = ctx->id;
 		}
 
-		exec[e].exec[0].handle = gem_create(fd, 4096);
-		exec[e].exec[0].offset = get_offset(ahnd, exec[e].exec[0].handle,
-						    4096, 0);
-		if (ahnd)
-			exec[e].exec[0].flags = EXEC_OBJECT_PINNED;
-
-		exec[e].cmd = gem_mmap__device_coherent(fd, exec[e].exec[0].handle,
-							0, 4096, PROT_WRITE);
-
-		gem_set_domain(fd, exec[e].exec[0].handle,
-			       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
-		exec[e].cmd[0] = MI_BATCH_BUFFER_END;
-
-		gem_execbuf(fd, &exec[e].execbuf);
-		exec[e].exec[1] = exec[e].exec[0];
-		exec[e].execbuf.buffer_count = 2;
-
-		exec[e].reloc.target_handle = 1; /* recurse */
-		exec[e].reloc.offset = sizeof(uint32_t);
-		exec[e].reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
-		if (gen < 4)
-			exec[e].reloc.delta = 1;
-
-		exec[e].exec[1].relocs_ptr = to_user_pointer(&exec[e].reloc);
-		exec[e].exec[1].relocation_count = !ahnd ? 1 : 0;
+		exec[e].exec[1].handle = gem_create(fd, 4096);
+		obj[nengine * ring_size + e] = exec[e].exec[1];
 	}
 
-	obj[nengine*ring_size].handle = gem_create(fd, 4096);
-	gem_write(fd, obj[nengine*ring_size].handle, 0, &bbe, sizeof(bbe));
-
-	obj[nengine*ring_size].offset = get_offset(ahnd, obj[nengine*ring_size].handle,
-						   4096, 0);
-	if (ahnd)
-		obj[nengine*ring_size].flags |= EXEC_OBJECT_PINNED;
+	obj[nengine * (ring_size + 1)].handle = gem_create(fd, 4096);
+	gem_write(fd, obj[nengine * (ring_size + 1)].handle, 0,
+		  &bbe, sizeof(bbe));
 
 	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(&obj[nengine*ring_size]);
-	execbuf.buffer_count = 1;
-	gem_execbuf(fd, &execbuf); /* tag the object as a batch in the GTT */
 	execbuf.buffers_ptr = to_user_pointer(obj);
-	execbuf.buffer_count = nengine*ring_size + 1;
+	execbuf.buffer_count = nengine * (ring_size + 1) + 1;
+	execbuf.rsvd1 = ctx->id;
+	gem_execbuf(fd, &execbuf); /* tag the object as a batch in the GTT */
+	for (unsigned e = 0; e < nengine; e++) {
+		uint64_t address;
+		uint32_t *cs;
+
+		for (unsigned n = 0; n < ring_size; n++) {
+			obj[e * ring_size + n].flags |= EXEC_OBJECT_PINNED;
+			exec[e].obj[n] = obj[e * ring_size + n];
+		}
+		exec[e].exec[1] = obj[nengine * ring_size + e];
+		exec[e].exec[1].flags |= EXEC_OBJECT_PINNED;
+		address = exec[e].exec[1].offset;
+
+		exec[e].cmd = gem_mmap__device_coherent(fd, exec[e].exec[1].handle,
+							0, 4096, PROT_WRITE);
+		cs = exec[e].cmd;
+
+		*cs++ = MI_NOOP;
+		if (gen >= 8) {
+			*cs++ = MI_BATCH_BUFFER_START | 1 << 8 | 1;
+			*cs++ = address;
+			*cs++ = address >> 32;
+		} else if (gen >= 6) {
+			*cs++ = MI_BATCH_BUFFER_START | 1 << 8;
+			*cs++ = address;
+		} else {
+			*cs++ = MI_BATCH_BUFFER_START | 2 << 6;
+			if (gen < 4)
+				address |= 1;
+			*cs++ = address;
+		}
+	}
 
 	intel_detect_and_clear_missed_interrupts(fd);
 
@@ -182,42 +190,22 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 	igt_until_timeout(timeout) {
 		struct timespec start, now;
 		for (unsigned e = 0; e < nengine; e++) {
-			uint64_t address;
-			int i;
-
 			if (flags & CONTEXTS) {
 				intel_ctx_destroy(fd, exec[e].ctx);
-				exec[e].ctx = intel_ctx_create(fd, &ctx->cfg);
+				exec[e].ctx = intel_ctx_create(fd, cfg);
 				exec[e].execbuf.rsvd1 = exec[e].ctx->id;
 			}
 
-			exec[e].reloc.presumed_offset = exec[e].exec[1].offset;
-			address = (exec[e].reloc.presumed_offset +
-				   exec[e].reloc.delta);
 			gem_set_domain(fd, exec[e].exec[1].handle,
 				       I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
+			exec[e].cmd[0] = MI_ARB_CHECK;
 
-			i = 0;
-			exec[e].cmd[i] = MI_BATCH_BUFFER_START;
-			if (gen >= 8) {
-				exec[e].cmd[i] |= 1 << 8 | 1;
-				exec[e].cmd[++i] = address;
-				exec[e].cmd[++i] = address >> 32;
-			} else if (gen >= 6) {
-				exec[e].cmd[i] |= 1 << 8;
-				exec[e].cmd[++i] = address;
-			} else {
-				exec[e].cmd[i] |= 2 << 6;
-				exec[e].cmd[++i] = address;
-			}
-
-			exec[e].exec[0] = obj[nengine*ring_size];
+			exec[e].exec[0] = obj[nengine * (ring_size + 1)];
 			gem_execbuf(fd, &exec[e].execbuf);
 
 			for (unsigned n = 0; n < ring_size; n++) {
 				exec[e].exec[0] = exec[e].obj[n];
 				gem_execbuf(fd, &exec[e].execbuf);
-				exec[e].obj[n].offset = exec[e].exec[0].offset;
 			}
 		}
 
@@ -225,10 +213,7 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 
 		clock_gettime(CLOCK_MONOTONIC, &start);
 		for (unsigned e = 0; e < nengine; e++) {
-			execbuf.flags = (engines[e] |
-					 I915_EXEC_NO_RELOC |
-					 I915_EXEC_HANDLE_LUT);
-			execbuf.rsvd1 = ctx->id;
+			execbuf.flags = engines[e];
 			gem_execbuf(fd, &execbuf);
 		}
 		clock_gettime(CLOCK_MONOTONIC, &now);
@@ -245,43 +230,40 @@ static void wide(int fd, const intel_ctx_t *ctx, int ring_size,
 	igt_info("%s: %'lu cycles: %.3fus\n",
 		 __func__, count, time*1e6 / count);
 
-	gem_close(fd, obj[nengine*ring_size].handle);
+	for (unsigned n = 0; n < nengine * (ring_size + 1) + 1; n++)
+		gem_close(fd, obj[n].handle);
 	free(obj);
 
 	for (unsigned e = 0; e < nengine; e++) {
 		if (flags & CONTEXTS)
 			intel_ctx_destroy(fd, exec[e].ctx);
 
-		for (unsigned n = 0; n < ring_size; n++) {
-			gem_close(fd, exec[e].obj[n].handle);
-			put_offset(ahnd, exec[e].obj[n].handle);
-		}
-		free(exec[e].obj);
-
 		munmap(exec[e].cmd, 4096);
-		gem_close(fd, exec[e].exec[1].handle);
-		put_offset(ahnd, exec[e].exec[1].handle);
+		free(exec[e].obj);
 	}
 	free(exec);
-	put_ahnd(ahnd);
+
+	intel_ctx_destroy(fd, ctx);
+	__gem_vm_destroy(fd, cfg->vm);
+	cfg->vm = 0;
 }
 
 #define TIMEOUT 20
 
 igt_main
 {
+	intel_ctx_cfg_t cfg;
 	int ring_size = 0;
-	int device = -1;
-	const intel_ctx_t *ctx;
+	igt_fd_t(device);
 
 	igt_fixture {
 
 		device = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(device);
 		gem_submission_print_method(device);
-		ctx = intel_ctx_create_all_physical(device);
+		cfg = intel_ctx_cfg_all_physical(device);
 
-		ring_size = gem_submission_measure(device, &ctx->cfg, ALL_ENGINES);
+		ring_size = gem_submission_measure(device, &cfg, ALL_ENGINES);
 
 		igt_info("Ring size: %d batches\n", ring_size);
 		igt_require(ring_size > 0);
@@ -290,16 +272,14 @@ igt_main
 	}
 
 	igt_subtest("wide-all")
-		wide(device, ctx, ring_size, TIMEOUT, 0);
+		wide(device, &cfg, ring_size, TIMEOUT, 0);
 
 	igt_subtest("wide-contexts") {
 		gem_require_contexts(device);
-		wide(device, ctx, ring_size, TIMEOUT, CONTEXTS);
+		wide(device, &cfg, ring_size, TIMEOUT, CONTEXTS);
 	}
 
 	igt_fixture {
 		igt_stop_hang_detector();
-		intel_ctx_destroy(device, ctx);
-		drm_close_driver(device);
 	}
 }
-- 
2.34.1

             reply	other threads:[~2023-07-06 16:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-06 16:00 Andrzej Hajda [this message]
2023-07-06 18:29 ` [igt-dev] ✗ Fi.CI.BAT: failure for i915/gem_exec_await: Avoid DG2 conflicts Patchwork
2023-07-06 19:30 ` [igt-dev] ○ CI.xeBAT: info " Patchwork
2023-07-07  9:49 ` [igt-dev] ✗ GitLab.Pipeline: warning for i915/gem_exec_await: Avoid DG2 conflicts (rev2) Patchwork
2023-07-07 10:21 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2023-07-07 10:32 ` [igt-dev] ○ CI.xeBAT: info " Patchwork
2023-07-07 15:14 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2023-07-14 12:49   ` [igt-dev] ✗ Fi.CI.IGT: failure for i915/https://gitlab.freedesktop.org/drm/intel/-/issues/5892: " Andrzej Hajda
2023-07-24 12:43 ` [igt-dev] [PATCH i-g-t] i915/gem_exec_await: Avoid DG2 conflicts Andrzej Hajda
2023-07-24 17:35 ` Kamil Konieczny

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=20230706160014.1027512-1-andrzej.hajda@intel.com \
    --to=andrzej.hajda@intel.com \
    --cc=chris.p.wilson@intel.com \
    --cc=chris.p.wilson@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=nirmoy.das@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox