All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 03/15] tests/i915/i915_hangman: Update capture test to use engine structure
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
  (?)
@ 2022-01-13 19:58   ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 19:58 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:35AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The capture test was still using old style ring_id and ring_name
> (derived from the engine structure at the higher level). Update it to
> just take the engine structure directly.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index f64b8819d..280eac197 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -207,8 +207,8 @@ static void check_error_state(const char *expected_ring_name,
>  	igt_assert(found);
>  }
>  
> -static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
> -				     const char *ring_name)
> +static void test_error_state_capture(const intel_ctx_t *ctx,
> +				     const struct intel_execution_engine2 *e)
>  {
>  	uint32_t *batch;
>  	igt_hang_t hang;
> @@ -217,7 +217,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
>  
>  	clear_error_state();
>  
> -	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, ring_id,
> +	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, e->flags,
>  				      HANG_ALLOW_CAPTURE);
>  	offset = hang.spin->obj[IGT_SPIN_BATCH].offset;
>  
> @@ -226,7 +226,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
>  
>  	igt_post_hang_ring(device, hang);
>  
> -	check_error_state(ring_name, offset, batch);
> +	check_error_state(e->name, offset, batch);
>  	munmap(batch, 4096);
>  	put_ahnd(ahnd);
>  }
> @@ -351,7 +351,7 @@ igt_main
>  	igt_subtest_with_dynamic("error-state-capture") {
>  		for_each_ctx_engine(device, ctx, e) {
>  			igt_dynamic_f("%s", e->name)
> -				test_error_state_capture(ctx, e->flags, e->name);
> +				test_error_state_capture(ctx, e);
>  		}
>  	}
>  
> -- 
> 2.25.1
> 

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

* [Intel-gfx] [PATCH v3 i-g-t 00/15] Fixes for i915_hangman and gem_exec_capture
@ 2022-01-13 19:59 ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Fix a bunch of issues with i915_hangman and gem_exec_capture with the
ultimate aim of making them pass on GuC enabled platforms.

v2: Fixes to the store code. Add engine properties management.
v3: Fix for platforms without pre-emption.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>


John Harrison (15):
  tests/i915/i915_hangman: Add descriptions
  lib/hang: Fix igt_require_hang_ring to work with all engines
  tests/i915/i915_hangman: Update capture test to use engine structure
  tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU
    reset
  tests/i915/i915_hangman: Add uevent test & fix detector
  tests/i915/i915_hangman: Use the correct context in
    hangcheck_unterminated
  lib/store: Refactor common store code into helper function
  tests/i915/i915_hangman: Add alive-ness test after error capture
  tests/i915/i915_hangman: Remove reliance on context persistance
  tests/i915/i915_hangman: Run background task on all engines
  tests/i915/i915_hangman: Don't let background contexts cause a ban
  tests/i915/gem_exec_fence: Configure correct context
  lib/i915: Add helper for non-destructive engine property updates
  tests/i915/i915_hangman: Configure engine properties for quicker hangs
  tests/i915/gem_exec_capture: Restore engines

 lib/i915/gem_engine_topology.c |  46 ++++++
 lib/i915/gem_engine_topology.h |   9 ++
 lib/igt_aux.c                  |   7 +
 lib/igt_gt.c                   |   6 +-
 lib/igt_gt.h                   |   2 +-
 lib/igt_store.c                |  96 +++++++++++++
 lib/igt_store.h                |  12 ++
 lib/meson.build                |   1 +
 tests/i915/gem_exec_capture.c  |  37 +++--
 tests/i915/gem_exec_fence.c    |  79 +---------
 tests/i915/i915_hangman.c      | 256 +++++++++++++++++++++++++++------
 11 files changed, 423 insertions(+), 128 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 00/15] Fixes for i915_hangman and gem_exec_capture
@ 2022-01-13 19:59 ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Fix a bunch of issues with i915_hangman and gem_exec_capture with the
ultimate aim of making them pass on GuC enabled platforms.

v2: Fixes to the store code. Add engine properties management.
v3: Fix for platforms without pre-emption.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>


John Harrison (15):
  tests/i915/i915_hangman: Add descriptions
  lib/hang: Fix igt_require_hang_ring to work with all engines
  tests/i915/i915_hangman: Update capture test to use engine structure
  tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU
    reset
  tests/i915/i915_hangman: Add uevent test & fix detector
  tests/i915/i915_hangman: Use the correct context in
    hangcheck_unterminated
  lib/store: Refactor common store code into helper function
  tests/i915/i915_hangman: Add alive-ness test after error capture
  tests/i915/i915_hangman: Remove reliance on context persistance
  tests/i915/i915_hangman: Run background task on all engines
  tests/i915/i915_hangman: Don't let background contexts cause a ban
  tests/i915/gem_exec_fence: Configure correct context
  lib/i915: Add helper for non-destructive engine property updates
  tests/i915/i915_hangman: Configure engine properties for quicker hangs
  tests/i915/gem_exec_capture: Restore engines

 lib/i915/gem_engine_topology.c |  46 ++++++
 lib/i915/gem_engine_topology.h |   9 ++
 lib/igt_aux.c                  |   7 +
 lib/igt_gt.c                   |   6 +-
 lib/igt_gt.h                   |   2 +-
 lib/igt_store.c                |  96 +++++++++++++
 lib/igt_store.h                |  12 ++
 lib/meson.build                |   1 +
 tests/i915/gem_exec_capture.c  |  37 +++--
 tests/i915/gem_exec_fence.c    |  79 +---------
 tests/i915/i915_hangman.c      | 256 +++++++++++++++++++++++++++------
 11 files changed, 423 insertions(+), 128 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 01/15] tests/i915/i915_hangman: Add descriptions
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added descriptions of the various sub-tests and the test as a whole.

v2: Added missing linefeed (spotted by Petri)

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 tests/i915/i915_hangman.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 4c18c22db..b9c4d9983 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -46,6 +46,8 @@
 static int device = -1;
 static int sysfs = -1;
 
+IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -315,9 +317,9 @@ static void hangcheck_unterminated(void)
 
 	gem_execbuf(device, &execbuf);
 	if (gem_wait(device, handle, &timeout_ns) != 0) {
-		/* need to manually trigger an hang to clean before failing */
+		/* need to manually trigger a hang to clean before failing */
 		igt_force_gpu_reset(device);
-		igt_assert_f(0, "unterminated batch did not trigger an hang!");
+		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
 }
 
@@ -341,9 +343,11 @@ igt_main
 		igt_require(has_error_state(sysfs));
 	}
 
+	igt_describe("Basic error capture");
 	igt_subtest("error-state-basic")
 		test_error_state_basic();
 
+	igt_describe("Per engine error capture");
 	igt_subtest_with_dynamic("error-state-capture") {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
@@ -351,6 +355,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Per engine hang recovery (spin)");
 	igt_subtest_with_dynamic("engine-hang") {
                 int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
@@ -369,6 +374,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Per engine hang recovery (invalid CS)");
 	igt_subtest_with_dynamic("engine-error") {
 		int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
@@ -386,6 +392,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
 		hangcheck_unterminated();
 
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 01/15] tests/i915/i915_hangman: Add descriptions
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX, Petri Latvala

From: John Harrison <John.C.Harrison@Intel.com>

Added descriptions of the various sub-tests and the test as a whole.

v2: Added missing linefeed (spotted by Petri)

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 tests/i915/i915_hangman.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 4c18c22db..b9c4d9983 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -46,6 +46,8 @@
 static int device = -1;
 static int sysfs = -1;
 
+IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -315,9 +317,9 @@ static void hangcheck_unterminated(void)
 
 	gem_execbuf(device, &execbuf);
 	if (gem_wait(device, handle, &timeout_ns) != 0) {
-		/* need to manually trigger an hang to clean before failing */
+		/* need to manually trigger a hang to clean before failing */
 		igt_force_gpu_reset(device);
-		igt_assert_f(0, "unterminated batch did not trigger an hang!");
+		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
 }
 
@@ -341,9 +343,11 @@ igt_main
 		igt_require(has_error_state(sysfs));
 	}
 
+	igt_describe("Basic error capture");
 	igt_subtest("error-state-basic")
 		test_error_state_basic();
 
+	igt_describe("Per engine error capture");
 	igt_subtest_with_dynamic("error-state-capture") {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
@@ -351,6 +355,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Per engine hang recovery (spin)");
 	igt_subtest_with_dynamic("engine-hang") {
                 int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
@@ -369,6 +374,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Per engine hang recovery (invalid CS)");
 	igt_subtest_with_dynamic("engine-error") {
 		int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
@@ -386,6 +392,7 @@ igt_main
 		}
 	}
 
+	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
 		hangcheck_unterminated();
 
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 02/15] lib/hang: Fix igt_require_hang_ring to work with all engines
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The above function was checking for valid rings via the old interface.
The new scheme is to check for engines on contexts as there are now
more engines than could be supported.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_gt.c              | 6 +++---
 lib/igt_gt.h              | 2 +-
 tests/i915/i915_hangman.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 7c7df95ee..50da512f2 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -122,12 +122,12 @@ static void eat_error_state(int dev)
  * to be done under hang injection.
  * Default: false
  */
-void igt_require_hang_ring(int fd, int ring)
+void igt_require_hang_ring(int fd, uint32_t ctx, int ring)
 {
 	if (!igt_check_boolean_env_var("IGT_HANG", true))
 		igt_skip("hang injection disabled by user [IGT_HANG=0]\n");
 
-	gem_require_ring(fd, ring);
+        igt_require(gem_context_has_engine(fd, ctx, ring));
 	gem_context_require_bannable(fd);
 	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
 		igt_require(has_gpu_reset(fd));
@@ -290,7 +290,7 @@ static igt_hang_t __igt_hang_ctx(int fd, uint64_t ahnd, uint32_t ctx, int ring,
 	igt_spin_t *spin;
 	unsigned ban;
 
-	igt_require_hang_ring(fd, ring);
+	igt_require_hang_ring(fd, ctx, ring);
 
 	/* check if non-default ctx submission is allowed */
 	igt_require(ctx == 0 || has_ctx_exec(fd, ring, ctx));
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index c5059817b..3d10349e4 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -31,7 +31,7 @@
 #include "i915/i915_drm_local.h"
 #include "i915_drm.h"
 
-void igt_require_hang_ring(int fd, int ring);
+void igt_require_hang_ring(int fd, uint32_t ctx, int ring);
 
 typedef struct igt_hang {
 	igt_spin_t *spin;
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index b9c4d9983..f64b8819d 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -295,7 +295,7 @@ test_engine_hang(const intel_ctx_t *ctx,
  * case and it takes a lot more time to wrap, so the acthd can potentially keep
  * increasing for a long time
  */
-static void hangcheck_unterminated(void)
+static void hangcheck_unterminated(const intel_ctx_t *ctx)
 {
 	/* timeout needs to be greater than ~5*hangcheck */
 	int64_t timeout_ns = 100ull * NSEC_PER_SEC; /* 100 seconds */
@@ -304,7 +304,7 @@ static void hangcheck_unterminated(void)
 	uint32_t handle;
 
 	igt_require(gem_uses_full_ppgtt(device));
-	igt_require_hang_ring(device, 0);
+	igt_require_hang_ring(device, ctx->id, 0);
 
 	handle = gem_create(device, 4096);
 
@@ -394,7 +394,7 @@ igt_main
 
 	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
-		hangcheck_unterminated();
+		hangcheck_unterminated(ctx);
 
 	igt_fixture {
 		igt_disallow_hang(device, hang);
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 02/15] lib/hang: Fix igt_require_hang_ring to work with all engines
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The above function was checking for valid rings via the old interface.
The new scheme is to check for engines on contexts as there are now
more engines than could be supported.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_gt.c              | 6 +++---
 lib/igt_gt.h              | 2 +-
 tests/i915/i915_hangman.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 7c7df95ee..50da512f2 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -122,12 +122,12 @@ static void eat_error_state(int dev)
  * to be done under hang injection.
  * Default: false
  */
-void igt_require_hang_ring(int fd, int ring)
+void igt_require_hang_ring(int fd, uint32_t ctx, int ring)
 {
 	if (!igt_check_boolean_env_var("IGT_HANG", true))
 		igt_skip("hang injection disabled by user [IGT_HANG=0]\n");
 
-	gem_require_ring(fd, ring);
+        igt_require(gem_context_has_engine(fd, ctx, ring));
 	gem_context_require_bannable(fd);
 	if (!igt_check_boolean_env_var("IGT_HANG_WITHOUT_RESET", false))
 		igt_require(has_gpu_reset(fd));
@@ -290,7 +290,7 @@ static igt_hang_t __igt_hang_ctx(int fd, uint64_t ahnd, uint32_t ctx, int ring,
 	igt_spin_t *spin;
 	unsigned ban;
 
-	igt_require_hang_ring(fd, ring);
+	igt_require_hang_ring(fd, ctx, ring);
 
 	/* check if non-default ctx submission is allowed */
 	igt_require(ctx == 0 || has_ctx_exec(fd, ring, ctx));
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index c5059817b..3d10349e4 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -31,7 +31,7 @@
 #include "i915/i915_drm_local.h"
 #include "i915_drm.h"
 
-void igt_require_hang_ring(int fd, int ring);
+void igt_require_hang_ring(int fd, uint32_t ctx, int ring);
 
 typedef struct igt_hang {
 	igt_spin_t *spin;
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index b9c4d9983..f64b8819d 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -295,7 +295,7 @@ test_engine_hang(const intel_ctx_t *ctx,
  * case and it takes a lot more time to wrap, so the acthd can potentially keep
  * increasing for a long time
  */
-static void hangcheck_unterminated(void)
+static void hangcheck_unterminated(const intel_ctx_t *ctx)
 {
 	/* timeout needs to be greater than ~5*hangcheck */
 	int64_t timeout_ns = 100ull * NSEC_PER_SEC; /* 100 seconds */
@@ -304,7 +304,7 @@ static void hangcheck_unterminated(void)
 	uint32_t handle;
 
 	igt_require(gem_uses_full_ppgtt(device));
-	igt_require_hang_ring(device, 0);
+	igt_require_hang_ring(device, ctx->id, 0);
 
 	handle = gem_create(device, 4096);
 
@@ -394,7 +394,7 @@ igt_main
 
 	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
-		hangcheck_unterminated();
+		hangcheck_unterminated(ctx);
 
 	igt_fixture {
 		igt_disallow_hang(device, hang);
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 03/15] tests/i915/i915_hangman: Update capture test to use engine structure
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The capture test was still using old style ring_id and ring_name
(derived from the engine structure at the higher level). Update it to
just take the engine structure directly.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index f64b8819d..280eac197 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -207,8 +207,8 @@ static void check_error_state(const char *expected_ring_name,
 	igt_assert(found);
 }
 
-static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
-				     const char *ring_name)
+static void test_error_state_capture(const intel_ctx_t *ctx,
+				     const struct intel_execution_engine2 *e)
 {
 	uint32_t *batch;
 	igt_hang_t hang;
@@ -217,7 +217,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
 
 	clear_error_state();
 
-	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, ring_id,
+	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, e->flags,
 				      HANG_ALLOW_CAPTURE);
 	offset = hang.spin->obj[IGT_SPIN_BATCH].offset;
 
@@ -226,7 +226,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
 
 	igt_post_hang_ring(device, hang);
 
-	check_error_state(ring_name, offset, batch);
+	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
 }
@@ -351,7 +351,7 @@ igt_main
 	igt_subtest_with_dynamic("error-state-capture") {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
-				test_error_state_capture(ctx, e->flags, e->name);
+				test_error_state_capture(ctx, e);
 		}
 	}
 
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 03/15] tests/i915/i915_hangman: Update capture test to use engine structure
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The capture test was still using old style ring_id and ring_name
(derived from the engine structure at the higher level). Update it to
just take the engine structure directly.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index f64b8819d..280eac197 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -207,8 +207,8 @@ static void check_error_state(const char *expected_ring_name,
 	igt_assert(found);
 }
 
-static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
-				     const char *ring_name)
+static void test_error_state_capture(const intel_ctx_t *ctx,
+				     const struct intel_execution_engine2 *e)
 {
 	uint32_t *batch;
 	igt_hang_t hang;
@@ -217,7 +217,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
 
 	clear_error_state();
 
-	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, ring_id,
+	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, e->flags,
 				      HANG_ALLOW_CAPTURE);
 	offset = hang.spin->obj[IGT_SPIN_BATCH].offset;
 
@@ -226,7 +226,7 @@ static void test_error_state_capture(const intel_ctx_t *ctx, unsigned ring_id,
 
 	igt_post_hang_ring(device, hang);
 
-	check_error_state(ring_name, offset, batch);
+	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
 }
@@ -351,7 +351,7 @@ igt_main
 	igt_subtest_with_dynamic("error-state-capture") {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
-				test_error_state_capture(ctx, e->flags, e->name);
+				test_error_state_capture(ctx, e);
 		}
 	}
 
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 04/15] tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU reset
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Although the hangman test was ensuring that *some* reset functionality
was enabled, it did not differentiate what kind. The infrastructure
required to choose between per engine reset or full GT reset was
recently added. So update this test to use it as well.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 76 +++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 27 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 280eac197..7b8390a6c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -323,40 +323,26 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 	}
 }
 
-igt_main
+static void do_tests(const char *name, const char *prefix,
+		     const intel_ctx_t *ctx)
 {
 	const struct intel_execution_engine2 *e;
-	const intel_ctx_t *ctx;
-	igt_hang_t hang = {};
-
-	igt_fixture {
-		device = drm_open_driver(DRIVER_INTEL);
-		igt_require_gem(device);
-
-		ctx = intel_ctx_create_all_physical(device);
-
-		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE);
-
-		sysfs = igt_sysfs_open(device);
-		igt_assert(sysfs != -1);
-
-		igt_require(has_error_state(sysfs));
-	}
+	char buff[256];
 
-	igt_describe("Basic error capture");
-	igt_subtest("error-state-basic")
-		test_error_state_basic();
-
-	igt_describe("Per engine error capture");
-	igt_subtest_with_dynamic("error-state-capture") {
+	snprintf(buff, sizeof(buff), "Per engine error capture (%s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-error-state-capture", prefix);
+	igt_subtest_with_dynamic(buff) {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
 				test_error_state_capture(ctx, e);
 		}
 	}
 
-	igt_describe("Per engine hang recovery (spin)");
-	igt_subtest_with_dynamic("engine-hang") {
+	snprintf(buff, sizeof(buff), "Per engine hang recovery (spin, %s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-engine-hang", prefix);
+	igt_subtest_with_dynamic(buff) {
                 int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
 			.param = I915_PARAM_HAS_GPU_RESET,
@@ -374,8 +360,10 @@ igt_main
 		}
 	}
 
-	igt_describe("Per engine hang recovery (invalid CS)");
-	igt_subtest_with_dynamic("engine-error") {
+	snprintf(buff, sizeof(buff), "Per engine hang recovery (invalid CS, %s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-engine-error", prefix);
+	igt_subtest_with_dynamic(buff) {
 		int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
 			.param = I915_PARAM_HAS_GPU_RESET,
@@ -391,11 +379,45 @@ igt_main
 				test_engine_hang(ctx, e, IGT_SPIN_INVALID_CS);
 		}
 	}
+}
+
+igt_main
+{
+	const intel_ctx_t *ctx;
+	igt_hang_t hang = {};
+
+	igt_fixture {
+		device = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(device);
+
+		ctx = intel_ctx_create_all_physical(device);
+
+		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE);
+
+		sysfs = igt_sysfs_open(device);
+		igt_assert(sysfs != -1);
+
+		igt_require(has_error_state(sysfs));
+	}
+
+	igt_describe("Basic error capture");
+	igt_subtest("error-state-basic")
+		test_error_state_basic();
 
 	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
 		hangcheck_unterminated(ctx);
 
+	do_tests("GT", "gt", ctx);
+
+	igt_fixture {
+		igt_disallow_hang(device, hang);
+
+		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+	}
+
+	do_tests("engine", "engine", ctx);
+
 	igt_fixture {
 		igt_disallow_hang(device, hang);
 		intel_ctx_destroy(device, ctx);
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 04/15] tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU reset
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Although the hangman test was ensuring that *some* reset functionality
was enabled, it did not differentiate what kind. The infrastructure
required to choose between per engine reset or full GT reset was
recently added. So update this test to use it as well.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 76 +++++++++++++++++++++++++--------------
 1 file changed, 49 insertions(+), 27 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 280eac197..7b8390a6c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -323,40 +323,26 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 	}
 }
 
-igt_main
+static void do_tests(const char *name, const char *prefix,
+		     const intel_ctx_t *ctx)
 {
 	const struct intel_execution_engine2 *e;
-	const intel_ctx_t *ctx;
-	igt_hang_t hang = {};
-
-	igt_fixture {
-		device = drm_open_driver(DRIVER_INTEL);
-		igt_require_gem(device);
-
-		ctx = intel_ctx_create_all_physical(device);
-
-		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE);
-
-		sysfs = igt_sysfs_open(device);
-		igt_assert(sysfs != -1);
-
-		igt_require(has_error_state(sysfs));
-	}
+	char buff[256];
 
-	igt_describe("Basic error capture");
-	igt_subtest("error-state-basic")
-		test_error_state_basic();
-
-	igt_describe("Per engine error capture");
-	igt_subtest_with_dynamic("error-state-capture") {
+	snprintf(buff, sizeof(buff), "Per engine error capture (%s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-error-state-capture", prefix);
+	igt_subtest_with_dynamic(buff) {
 		for_each_ctx_engine(device, ctx, e) {
 			igt_dynamic_f("%s", e->name)
 				test_error_state_capture(ctx, e);
 		}
 	}
 
-	igt_describe("Per engine hang recovery (spin)");
-	igt_subtest_with_dynamic("engine-hang") {
+	snprintf(buff, sizeof(buff), "Per engine hang recovery (spin, %s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-engine-hang", prefix);
+	igt_subtest_with_dynamic(buff) {
                 int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
 			.param = I915_PARAM_HAS_GPU_RESET,
@@ -374,8 +360,10 @@ igt_main
 		}
 	}
 
-	igt_describe("Per engine hang recovery (invalid CS)");
-	igt_subtest_with_dynamic("engine-error") {
+	snprintf(buff, sizeof(buff), "Per engine hang recovery (invalid CS, %s reset)", name);
+	igt_describe(buff);
+	snprintf(buff, sizeof(buff), "%s-engine-error", prefix);
+	igt_subtest_with_dynamic(buff) {
 		int has_gpu_reset = 0;
 		struct drm_i915_getparam gp = {
 			.param = I915_PARAM_HAS_GPU_RESET,
@@ -391,11 +379,45 @@ igt_main
 				test_engine_hang(ctx, e, IGT_SPIN_INVALID_CS);
 		}
 	}
+}
+
+igt_main
+{
+	const intel_ctx_t *ctx;
+	igt_hang_t hang = {};
+
+	igt_fixture {
+		device = drm_open_driver(DRIVER_INTEL);
+		igt_require_gem(device);
+
+		ctx = intel_ctx_create_all_physical(device);
+
+		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE);
+
+		sysfs = igt_sysfs_open(device);
+		igt_assert(sysfs != -1);
+
+		igt_require(has_error_state(sysfs));
+	}
+
+	igt_describe("Basic error capture");
+	igt_subtest("error-state-basic")
+		test_error_state_basic();
 
 	igt_describe("Check that executing unintialised memory causes a hang");
 	igt_subtest("hangcheck-unterminated")
 		hangcheck_unterminated(ctx);
 
+	do_tests("GT", "gt", ctx);
+
+	igt_fixture {
+		igt_disallow_hang(device, hang);
+
+		hang = igt_allow_hang(device, ctx->id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+	}
+
+	do_tests("engine", "engine", ctx);
+
 	igt_fixture {
 		igt_disallow_hang(device, hang);
 		intel_ctx_destroy(device, ctx);
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 05/15] tests/i915/i915_hangman: Add uevent test & fix detector
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (4 preceding siblings ...)
  (?)
@ 2022-01-13 19:59 ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Some of the IGT framework relies on receving a uevent when a hang
occurs. So add a test that this actually works.

While testing this, noticed that hangs could sometimes be missed
because the uevent was (presumably) still in flight by the time the
handler was de-registered. So add an extra delay during cleanup to
give the uevent chance to arrive.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_aux.c             |  7 +++++++
 tests/i915/i915_hangman.c | 43 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index c247a1aa4..03cc38c93 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -523,6 +523,13 @@ void igt_fork_hang_detector(int fd)
 
 void igt_stop_hang_detector(void)
 {
+	/*
+	 * Give the uevent time to arrive. No sleep at all misses about 20% of
+	 * hangs (at least, in the i915_hangman/detector test). A sleep of 1ms
+	 * seems to miss about 2%, 10ms loses <1%, so 100ms should be safe.
+	 */
+	usleep(100 * 1000);
+
 	igt_stop_helper(&hang_detector);
 }
 
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 7b8390a6c..354769f39 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <signal.h>
 
 #include "i915/gem.h"
 #include "i915/gem_create.h"
@@ -289,6 +290,38 @@ test_engine_hang(const intel_ctx_t *ctx,
 	put_ahnd(ahnd);
 }
 
+static int hang_count;
+
+static void sig_io(int sig)
+{
+	hang_count++;
+}
+
+static void test_hang_detector(const intel_ctx_t *ctx,
+			       const struct intel_execution_engine2 *e)
+{
+	igt_hang_t hang;
+	uint64_t ahnd = get_reloc_ahnd(device, ctx->id);
+
+	hang_count = 0;
+
+	igt_fork_hang_detector(device);
+
+	/* Steal the signal handler */
+	signal(SIGIO, sig_io);
+
+	/* Make a hang... */
+	hang = igt_hang_ctx_with_ahnd(device, ahnd, ctx->id, e->flags, 0);
+
+	igt_post_hang_ring(device, hang);
+	put_ahnd(ahnd);
+
+	igt_stop_hang_detector();
+
+	/* Did it work? */
+	igt_assert(hang_count == 1);
+}
+
 /* This test covers the case where we end up in an uninitialised area of the
  * ppgtt and keep executing through it. This is particularly relevant if 48b
  * ppgtt is enabled because the ppgtt is massively bigger compared to the 32b
@@ -408,6 +441,16 @@ igt_main
 	igt_subtest("hangcheck-unterminated")
 		hangcheck_unterminated(ctx);
 
+	igt_describe("Check that hang detector works");
+	igt_subtest_with_dynamic("detector") {
+		const struct intel_execution_engine2 *e;
+
+		for_each_ctx_engine(device, ctx, e) {
+			igt_dynamic_f("%s", e->name)
+				test_hang_detector(ctx, e);
+		}
+	}
+
 	do_tests("GT", "gt", ctx);
 
 	igt_fixture {
-- 
2.25.1


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

* [Intel-gfx] [PATCH v3 i-g-t 06/15] tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (5 preceding siblings ...)
  (?)
@ 2022-01-13 19:59 ` John.C.Harrison
  2022-01-13 20:00     ` [igt-dev] " Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The hangman framework sets up a context that is valid for all engines
and has things like banning disabled. The 'unterminated' test then
ignores it and uses the default context. Fix that.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 354769f39..6656b3fcd 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -347,6 +347,7 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 	memset(&execbuf, 0, sizeof(execbuf));
 	execbuf.buffers_ptr = (uintptr_t)&gem_exec;
 	execbuf.buffer_count = 1;
+	execbuf.rsvd1 = ctx->id;
 
 	gem_execbuf(device, &execbuf);
 	if (gem_wait(device, handle, &timeout_ns) != 0) {
-- 
2.25.1


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

* [Intel-gfx] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

A lot of tests use almost identical code for creating a batch buffer
which does a single write to memory and another is about to be added.
Instead, move the most generic version into a common helper function.
Unfortunately, the other instances are all subtly different enough to
make it not so trivial to try to use the helper. It could be done but
it is unclear if it is worth the effort at this point. This patch
proves the concept, if people like it enough then it can be extended.

v2: Fix up object address vs store offset confusion (with help from
Zbigniew K).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
 lib/igt_store.h             | 12 +++++
 lib/meson.build             |  1 +
 tests/i915/gem_exec_fence.c | 77 ++---------------------------
 tests/i915/i915_hangman.c   |  1 +
 5 files changed, 115 insertions(+), 72 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

diff --git a/lib/igt_store.c b/lib/igt_store.c
new file mode 100644
index 000000000..42c888b55
--- /dev/null
+++ b/lib/igt_store.c
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915/gem_create.h"
+#include "igt_core.h"
+#include "drmtest.h"
+#include "igt_store.h"
+#include "intel_chipset.h"
+#include "intel_reg.h"
+#include "ioctl_wrappers.h"
+#include "lib/intel_allocator.h"
+
+/**
+ * SECTION:igt_store_word
+ * @short_description: Library for writing a value to memory
+ * @title: StoreWord
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some mechanism for writing a value to memory
+ * as a test that a batch buffer has executed.
+ *
+ * NB: Requires master for STORE_DWORD on gen4/5.
+ */
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value)
+{
+	const int SCRATCH = 0;
+	const int BATCH = 1;
+	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t batch[16], delta;
+	uint64_t bb_offset;
+	int i;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = ARRAY_SIZE(obj);
+	execbuf.flags = e->flags;
+	execbuf.rsvd1 = ctx->id;
+	if (fence != -1) {
+		execbuf.flags |= I915_EXEC_FENCE_IN;
+		execbuf.rsvd2 = fence;
+	}
+	if (gen < 6)
+		execbuf.flags |= I915_EXEC_SECURE;
+
+	memset(obj, 0, sizeof(obj));
+	obj[SCRATCH].handle = target_handle;
+
+	obj[BATCH].handle = gem_create(fd, 4096);
+	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
+	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
+	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
+	memset(&reloc, 0, sizeof(reloc));
+
+	i = 0;
+	delta = sizeof(uint32_t) * store_offset;
+	if (!ahnd) {
+		reloc.target_handle = obj[SCRATCH].handle;
+		reloc.presumed_offset = -1;
+		reloc.offset = sizeof(uint32_t) * (i + 1);
+		reloc.delta = delta;
+		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
+	} else {
+		obj[SCRATCH].offset = target_gpu_addr;
+		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
+		obj[BATCH].offset = bb_offset;
+		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
+	}
+	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
+	if (gen >= 8) {
+		batch[++i] = target_gpu_addr + delta;
+		batch[++i] = (target_gpu_addr + delta) >> 32;
+	} else if (gen >= 4) {
+		batch[++i] = 0;
+		batch[++i] = delta;
+		reloc.offset += sizeof(uint32_t);
+	} else {
+		batch[i]--;
+		batch[++i] = delta;
+	}
+	batch[++i] = store_value;
+	batch[++i] = MI_BATCH_BUFFER_END;
+	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[BATCH].handle);
+	put_offset(ahnd, obj[BATCH].handle);
+}
diff --git a/lib/igt_store.h b/lib/igt_store.h
new file mode 100644
index 000000000..5c6c8263c
--- /dev/null
+++ b/lib/igt_store.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "igt_gt.h"
+
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value);
diff --git a/lib/meson.build b/lib/meson.build
index b9568a71b..3e43316d1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -72,6 +72,7 @@ lib_sources = [
 	'igt_map.c',
 	'igt_pm.c',
 	'igt_dummyload.c',
+	'igt_store.c',
 	'uwildmat/uwildmat.c',
 	'igt_kmod.c',
 	'igt_panfrost.c',
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 9a6336ce9..196236b27 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -28,6 +28,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_syncobj.h"
 #include "igt_sysfs.h"
 #include "igt_vgem.h"
@@ -57,74 +58,6 @@ struct sync_merge_data {
 #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
 #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
 
-static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
-		  const struct intel_execution_engine2 *e,
-		  int fence, uint32_t target, uint64_t target_offset,
-		  unsigned offset_value)
-{
-	const int SCRATCH = 0;
-	const int BATCH = 1;
-	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
-	struct drm_i915_gem_exec_object2 obj[2];
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	uint32_t batch[16], delta;
-	uint64_t bb_offset;
-	int i;
-
-	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(obj);
-	execbuf.buffer_count = 2;
-	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
-	execbuf.rsvd1 = ctx->id;
-	execbuf.rsvd2 = fence;
-	if (gen < 6)
-		execbuf.flags |= I915_EXEC_SECURE;
-
-	memset(obj, 0, sizeof(obj));
-	obj[SCRATCH].handle = target;
-
-	obj[BATCH].handle = gem_create(fd, 4096);
-	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
-	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
-	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
-	memset(&reloc, 0, sizeof(reloc));
-
-	i = 0;
-	delta = sizeof(uint32_t) * offset_value;
-	if (!ahnd) {
-		reloc.target_handle = obj[SCRATCH].handle;
-		reloc.presumed_offset = -1;
-		reloc.offset = sizeof(uint32_t) * (i + 1);
-		reloc.delta = delta;
-		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
-	} else {
-		obj[SCRATCH].offset = target_offset;
-		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
-		obj[BATCH].offset = bb_offset;
-		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
-	}
-	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
-	if (gen >= 8) {
-		batch[++i] = target_offset + delta;
-		batch[++i] = target_offset >> 32;
-	} else if (gen >= 4) {
-		batch[++i] = 0;
-		batch[++i] = delta;
-		reloc.offset += sizeof(uint32_t);
-	} else {
-		batch[i]--;
-		batch[++i] = delta;
-	}
-	batch[++i] = offset_value;
-	batch[++i] = MI_BATCH_BUFFER_END;
-	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
-	gem_execbuf(fd, &execbuf);
-	gem_close(fd, obj[BATCH].handle);
-	put_offset(ahnd, obj[BATCH].handle);
-}
-
 static bool fence_busy(int fence)
 {
 	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
@@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
 			continue;
 
 		if (flags & NONBLOCK) {
-			store(fd, ahnd, ctx, e2, spin->out_fence,
-			      scratch, scratch_offset, i);
+			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+				       scratch, scratch_offset, i, i);
 		} else {
 			igt_fork(child, 1) {
 				ahnd = get_reloc_ahnd(fd, ctx->id);
-				store(fd, ahnd, ctx, e2, spin->out_fence,
-				      scratch, scratch_offset, i);
+				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+					       scratch, scratch_offset, i, i);
 				put_ahnd(ahnd);
 			}
 		}
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 6656b3fcd..5a0c9497c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -36,6 +36,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_sysfs.h"
 #include "igt_debugfs.h"
 #include "sw_sync.h"
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

A lot of tests use almost identical code for creating a batch buffer
which does a single write to memory and another is about to be added.
Instead, move the most generic version into a common helper function.
Unfortunately, the other instances are all subtly different enough to
make it not so trivial to try to use the helper. It could be done but
it is unclear if it is worth the effort at this point. This patch
proves the concept, if people like it enough then it can be extended.

v2: Fix up object address vs store offset confusion (with help from
Zbigniew K).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
 lib/igt_store.h             | 12 +++++
 lib/meson.build             |  1 +
 tests/i915/gem_exec_fence.c | 77 ++---------------------------
 tests/i915/i915_hangman.c   |  1 +
 5 files changed, 115 insertions(+), 72 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

diff --git a/lib/igt_store.c b/lib/igt_store.c
new file mode 100644
index 000000000..42c888b55
--- /dev/null
+++ b/lib/igt_store.c
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915/gem_create.h"
+#include "igt_core.h"
+#include "drmtest.h"
+#include "igt_store.h"
+#include "intel_chipset.h"
+#include "intel_reg.h"
+#include "ioctl_wrappers.h"
+#include "lib/intel_allocator.h"
+
+/**
+ * SECTION:igt_store_word
+ * @short_description: Library for writing a value to memory
+ * @title: StoreWord
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some mechanism for writing a value to memory
+ * as a test that a batch buffer has executed.
+ *
+ * NB: Requires master for STORE_DWORD on gen4/5.
+ */
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value)
+{
+	const int SCRATCH = 0;
+	const int BATCH = 1;
+	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t batch[16], delta;
+	uint64_t bb_offset;
+	int i;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = ARRAY_SIZE(obj);
+	execbuf.flags = e->flags;
+	execbuf.rsvd1 = ctx->id;
+	if (fence != -1) {
+		execbuf.flags |= I915_EXEC_FENCE_IN;
+		execbuf.rsvd2 = fence;
+	}
+	if (gen < 6)
+		execbuf.flags |= I915_EXEC_SECURE;
+
+	memset(obj, 0, sizeof(obj));
+	obj[SCRATCH].handle = target_handle;
+
+	obj[BATCH].handle = gem_create(fd, 4096);
+	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
+	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
+	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
+	memset(&reloc, 0, sizeof(reloc));
+
+	i = 0;
+	delta = sizeof(uint32_t) * store_offset;
+	if (!ahnd) {
+		reloc.target_handle = obj[SCRATCH].handle;
+		reloc.presumed_offset = -1;
+		reloc.offset = sizeof(uint32_t) * (i + 1);
+		reloc.delta = delta;
+		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
+	} else {
+		obj[SCRATCH].offset = target_gpu_addr;
+		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
+		obj[BATCH].offset = bb_offset;
+		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
+	}
+	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
+	if (gen >= 8) {
+		batch[++i] = target_gpu_addr + delta;
+		batch[++i] = (target_gpu_addr + delta) >> 32;
+	} else if (gen >= 4) {
+		batch[++i] = 0;
+		batch[++i] = delta;
+		reloc.offset += sizeof(uint32_t);
+	} else {
+		batch[i]--;
+		batch[++i] = delta;
+	}
+	batch[++i] = store_value;
+	batch[++i] = MI_BATCH_BUFFER_END;
+	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[BATCH].handle);
+	put_offset(ahnd, obj[BATCH].handle);
+}
diff --git a/lib/igt_store.h b/lib/igt_store.h
new file mode 100644
index 000000000..5c6c8263c
--- /dev/null
+++ b/lib/igt_store.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "igt_gt.h"
+
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value);
diff --git a/lib/meson.build b/lib/meson.build
index b9568a71b..3e43316d1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -72,6 +72,7 @@ lib_sources = [
 	'igt_map.c',
 	'igt_pm.c',
 	'igt_dummyload.c',
+	'igt_store.c',
 	'uwildmat/uwildmat.c',
 	'igt_kmod.c',
 	'igt_panfrost.c',
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 9a6336ce9..196236b27 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -28,6 +28,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_syncobj.h"
 #include "igt_sysfs.h"
 #include "igt_vgem.h"
@@ -57,74 +58,6 @@ struct sync_merge_data {
 #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
 #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
 
-static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
-		  const struct intel_execution_engine2 *e,
-		  int fence, uint32_t target, uint64_t target_offset,
-		  unsigned offset_value)
-{
-	const int SCRATCH = 0;
-	const int BATCH = 1;
-	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
-	struct drm_i915_gem_exec_object2 obj[2];
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	uint32_t batch[16], delta;
-	uint64_t bb_offset;
-	int i;
-
-	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(obj);
-	execbuf.buffer_count = 2;
-	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
-	execbuf.rsvd1 = ctx->id;
-	execbuf.rsvd2 = fence;
-	if (gen < 6)
-		execbuf.flags |= I915_EXEC_SECURE;
-
-	memset(obj, 0, sizeof(obj));
-	obj[SCRATCH].handle = target;
-
-	obj[BATCH].handle = gem_create(fd, 4096);
-	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
-	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
-	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
-	memset(&reloc, 0, sizeof(reloc));
-
-	i = 0;
-	delta = sizeof(uint32_t) * offset_value;
-	if (!ahnd) {
-		reloc.target_handle = obj[SCRATCH].handle;
-		reloc.presumed_offset = -1;
-		reloc.offset = sizeof(uint32_t) * (i + 1);
-		reloc.delta = delta;
-		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
-	} else {
-		obj[SCRATCH].offset = target_offset;
-		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
-		obj[BATCH].offset = bb_offset;
-		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
-	}
-	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
-	if (gen >= 8) {
-		batch[++i] = target_offset + delta;
-		batch[++i] = target_offset >> 32;
-	} else if (gen >= 4) {
-		batch[++i] = 0;
-		batch[++i] = delta;
-		reloc.offset += sizeof(uint32_t);
-	} else {
-		batch[i]--;
-		batch[++i] = delta;
-	}
-	batch[++i] = offset_value;
-	batch[++i] = MI_BATCH_BUFFER_END;
-	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
-	gem_execbuf(fd, &execbuf);
-	gem_close(fd, obj[BATCH].handle);
-	put_offset(ahnd, obj[BATCH].handle);
-}
-
 static bool fence_busy(int fence)
 {
 	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
@@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
 			continue;
 
 		if (flags & NONBLOCK) {
-			store(fd, ahnd, ctx, e2, spin->out_fence,
-			      scratch, scratch_offset, i);
+			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+				       scratch, scratch_offset, i, i);
 		} else {
 			igt_fork(child, 1) {
 				ahnd = get_reloc_ahnd(fd, ctx->id);
-				store(fd, ahnd, ctx, e2, spin->out_fence,
-				      scratch, scratch_offset, i);
+				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+					       scratch, scratch_offset, i, i);
 				put_ahnd(ahnd);
 			}
 		}
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 6656b3fcd..5a0c9497c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -36,6 +36,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_sysfs.h"
 #include "igt_debugfs.h"
 #include "sw_sync.h"
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 08/15] tests/i915/i915_hangman: Add alive-ness test after error capture
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added a an extra step to the i915_hangman tests to check that the
system is still alive after the hang and recovery. This submits a
simple batch to each engine which does a write to memory and checks
that the write occurred.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 5a0c9497c..918418760 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -48,8 +48,57 @@
 static int device = -1;
 static int sysfs = -1;
 
+#define OFFSET_ALIVE	10
+
 IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
 
+static void check_alive(void)
+{
+	const struct intel_execution_engine2 *engine;
+	const intel_ctx_t *ctx;
+	uint32_t scratch, *out;
+	int fd, i = 0;
+	uint64_t ahnd, scratch_addr;
+
+	fd = drm_open_driver(DRIVER_INTEL);
+	igt_require(gem_class_can_store_dword(fd, 0));
+
+	ctx = intel_ctx_create_all_physical(fd);
+	ahnd = get_reloc_ahnd(fd, ctx->id);
+	scratch = gem_create(fd, 4096);
+	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
+	out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
+	gem_set_domain(fd, scratch,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	for_each_physical_engine(fd, engine) {
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
+		i++;
+	}
+
+	i = 0;
+	for_each_ctx_engine(fd, ctx, engine) {
+		if (!gem_class_can_store_dword(fd, engine->class))
+			continue;
+
+		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
+		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
+			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
+		i++;
+	}
+
+	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
+
+	while (i--)
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
+
+	munmap(out, 4096);
+	gem_close(fd, scratch);
+	put_ahnd(ahnd);
+	intel_ctx_destroy(fd, ctx);
+	close(fd);
+}
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static void
@@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
 		put_ahnd(ahndN);
 	}
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static int hang_count;
@@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
 
 	/* Did it work? */
 	igt_assert(hang_count == 1);
+
+	check_alive();
 }
 
 /* This test covers the case where we end up in an uninitialised area of the
@@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 		igt_force_gpu_reset(device);
 		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
+
+	check_alive();
 }
 
 static void do_tests(const char *name, const char *prefix,
@@ -433,6 +490,8 @@ igt_main
 		igt_assert(sysfs != -1);
 
 		igt_require(has_error_state(sysfs));
+
+		gem_require_mmap_wc(device);
 	}
 
 	igt_describe("Basic error capture");
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 08/15] tests/i915/i915_hangman: Add alive-ness test after error capture
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added a an extra step to the i915_hangman tests to check that the
system is still alive after the hang and recovery. This submits a
simple batch to each engine which does a write to memory and checks
that the write occurred.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 5a0c9497c..918418760 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -48,8 +48,57 @@
 static int device = -1;
 static int sysfs = -1;
 
+#define OFFSET_ALIVE	10
+
 IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
 
+static void check_alive(void)
+{
+	const struct intel_execution_engine2 *engine;
+	const intel_ctx_t *ctx;
+	uint32_t scratch, *out;
+	int fd, i = 0;
+	uint64_t ahnd, scratch_addr;
+
+	fd = drm_open_driver(DRIVER_INTEL);
+	igt_require(gem_class_can_store_dword(fd, 0));
+
+	ctx = intel_ctx_create_all_physical(fd);
+	ahnd = get_reloc_ahnd(fd, ctx->id);
+	scratch = gem_create(fd, 4096);
+	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
+	out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
+	gem_set_domain(fd, scratch,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	for_each_physical_engine(fd, engine) {
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
+		i++;
+	}
+
+	i = 0;
+	for_each_ctx_engine(fd, ctx, engine) {
+		if (!gem_class_can_store_dword(fd, engine->class))
+			continue;
+
+		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
+		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
+			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
+		i++;
+	}
+
+	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
+
+	while (i--)
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
+
+	munmap(out, 4096);
+	gem_close(fd, scratch);
+	put_ahnd(ahnd);
+	intel_ctx_destroy(fd, ctx);
+	close(fd);
+}
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static void
@@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
 		put_ahnd(ahndN);
 	}
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static int hang_count;
@@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
 
 	/* Did it work? */
 	igt_assert(hang_count == 1);
+
+	check_alive();
 }
 
 /* This test covers the case where we end up in an uninitialised area of the
@@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 		igt_force_gpu_reset(device);
 		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
+
+	check_alive();
 }
 
 static void do_tests(const char *name, const char *prefix,
@@ -433,6 +490,8 @@ igt_main
 		igt_assert(sysfs != -1);
 
 		igt_require(has_error_state(sysfs));
+
+		gem_require_mmap_wc(device);
 	}
 
 	igt_describe("Basic error capture");
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The hang test was relying on context persitence for no particular
reason. That is, it would set a bunch of background spinners running
then immediately destroy the active contexts but expect the spinners
to keep spinning. With the current implementation of context
persistence in i915, that means that super high priority pings are
sent to each engine at the start of the test. Depending upon the
timing and platform, one of those unexpected pings could cause test
failures.

There is no need to require context persitence in this test. So change
to managing the contexts cleanly and only destroying them when they
are no longer in use.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 918418760..6601db5f6 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
 		 const struct intel_execution_engine2 *e, unsigned int flags)
 {
 	const struct intel_execution_engine2 *other;
-	const intel_ctx_t *tmp_ctx;
+	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];
 	igt_spin_t *spin, *next;
 	IGT_LIST_HEAD(list);
 	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
+	int num_ctx;
 
 	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
 		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
 
 	/* Fill all the other engines with background load */
+	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
 		if (other->flags == e->flags)
 			continue;
 
-		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
-		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
+		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
+		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
 				      .ahnd = ahndN,
-				      .ctx = tmp_ctx,
+				      .ctx = local_ctx[num_ctx],
 				      .engine = other->flags,
 				      .flags = IGT_SPIN_FENCE_OUT);
-		intel_ctx_destroy(device, tmp_ctx);
+		num_ctx++;
 
 		igt_list_move(&spin->link, &list);
 	}
@@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
 		igt_spin_free(device, spin);
 		put_ahnd(ahndN);
 	}
+
 	put_ahnd(ahnd);
+	while (num_ctx)
+		intel_ctx_destroy(device, local_ctx[--num_ctx]);
 
 	check_alive();
 }
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The hang test was relying on context persitence for no particular
reason. That is, it would set a bunch of background spinners running
then immediately destroy the active contexts but expect the spinners
to keep spinning. With the current implementation of context
persistence in i915, that means that super high priority pings are
sent to each engine at the start of the test. Depending upon the
timing and platform, one of those unexpected pings could cause test
failures.

There is no need to require context persitence in this test. So change
to managing the contexts cleanly and only destroying them when they
are no longer in use.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 918418760..6601db5f6 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
 		 const struct intel_execution_engine2 *e, unsigned int flags)
 {
 	const struct intel_execution_engine2 *other;
-	const intel_ctx_t *tmp_ctx;
+	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];
 	igt_spin_t *spin, *next;
 	IGT_LIST_HEAD(list);
 	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
+	int num_ctx;
 
 	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
 		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
 
 	/* Fill all the other engines with background load */
+	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
 		if (other->flags == e->flags)
 			continue;
 
-		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
-		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
+		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
+		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
 				      .ahnd = ahndN,
-				      .ctx = tmp_ctx,
+				      .ctx = local_ctx[num_ctx],
 				      .engine = other->flags,
 				      .flags = IGT_SPIN_FENCE_OUT);
-		intel_ctx_destroy(device, tmp_ctx);
+		num_ctx++;
 
 		igt_list_move(&spin->link, &list);
 	}
@@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
 		igt_spin_free(device, spin);
 		put_ahnd(ahndN);
 	}
+
 	put_ahnd(ahnd);
+	while (num_ctx)
+		intel_ctx_destroy(device, local_ctx[--num_ctx]);
 
 	check_alive();
 }
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 10/15] tests/i915/i915_hangman: Run background task on all engines
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (9 preceding siblings ...)
  (?)
@ 2022-01-13 19:59 ` John.C.Harrison
  2022-01-13 20:48     ` [igt-dev] " Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

As opposed to only on the non-target engines. This means that there is
some other workload present for the scheduler to switch between and so
detet the hang immediately.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 6601db5f6..9f7f8062c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -298,12 +298,14 @@ test_engine_hang(const intel_ctx_t *ctx,
 	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
 		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
 
-	/* Fill all the other engines with background load */
+	/*
+	 * Fill all engines with background load.
+	 * This verifies that independent engines are unaffected and gives
+	 * the target engine something to switch between so it notices the
+	 * hang.
+	 */
 	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
-		if (other->flags == e->flags)
-			continue;
-
 		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
 		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
-- 
2.25.1


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

* [Intel-gfx] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The global context used by all the subtests for causing hangs is
marked as unbannable. However, some of the subtests set background
spinners running on all engines using a freshly created context. If
there is a test failure for any reason, all of those spinners can be
killed off as hanging contexts. On systems with lots of engines, that
can result in the test being banned from creating any new contexts.

So make the spinner contexts unbannable as well. That way if one
subtest fails it won't necessarily bring down all subsequent subtests.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 9f7f8062c..567eb71ee 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_alive();
 }
 
+static void context_unban(int fd, unsigned ctx)
+{
+	struct drm_i915_gem_context_param param = {
+		.ctx_id = ctx,
+		.param = I915_CONTEXT_PARAM_BANNABLE,
+		.value = 0,
+	};
+
+	if(__gem_context_set_param(fd, &param) == -EINVAL) {
+		igt_assert_eq(param.value, 0);
+		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
+		gem_context_set_param(fd, &param);
+	}
+}
+
 static void
 test_engine_hang(const intel_ctx_t *ctx,
 		 const struct intel_execution_engine2 *e, unsigned int flags)
@@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
 	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
 		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
+		context_unban(device, local_ctx[num_ctx]->id);
 		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
 				      .ahnd = ahndN,
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The global context used by all the subtests for causing hangs is
marked as unbannable. However, some of the subtests set background
spinners running on all engines using a freshly created context. If
there is a test failure for any reason, all of those spinners can be
killed off as hanging contexts. On systems with lots of engines, that
can result in the test being banned from creating any new contexts.

So make the spinner contexts unbannable as well. That way if one
subtest fails it won't necessarily bring down all subsequent subtests.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 9f7f8062c..567eb71ee 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_alive();
 }
 
+static void context_unban(int fd, unsigned ctx)
+{
+	struct drm_i915_gem_context_param param = {
+		.ctx_id = ctx,
+		.param = I915_CONTEXT_PARAM_BANNABLE,
+		.value = 0,
+	};
+
+	if(__gem_context_set_param(fd, &param) == -EINVAL) {
+		igt_assert_eq(param.value, 0);
+		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
+		gem_context_set_param(fd, &param);
+	}
+}
+
 static void
 test_engine_hang(const intel_ctx_t *ctx,
 		 const struct intel_execution_engine2 *e, unsigned int flags)
@@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
 	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
 		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
+		context_unban(device, local_ctx[num_ctx]->id);
 		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
 				      .ahnd = ahndN,
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The update to use intel_ctx_t missed a line that configures the
context to allow hanging. Fix that.

Fixes: 09c36188b23f83ef9a7b5414e2a10100adc4291f

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/gem_exec_fence.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 196236b27..5e45d0518 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -3139,7 +3139,7 @@ igt_main
 			igt_hang_t hang;
 
 			igt_fixture {
-				hang = igt_allow_hang(i915, 0, 0);
+				hang = igt_allow_hang(i915, ctx->id, 0);
 				intel_allocator_multiprocess_start();
 			}
 
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The update to use intel_ctx_t missed a line that configures the
context to allow hanging. Fix that.

Fixes: 09c36188b23f83ef9a7b5414e2a10100adc4291f

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/gem_exec_fence.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 196236b27..5e45d0518 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -3139,7 +3139,7 @@ igt_main
 			igt_hang_t hang;
 
 			igt_fixture {
-				hang = igt_allow_hang(i915, 0, 0);
+				hang = igt_allow_hang(i915, ctx->id, 0);
 				intel_allocator_multiprocess_start();
 			}
 
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 13/15] lib/i915: Add helper for non-destructive engine property updates
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Various tests want to configure engine properties such as pre-emption
timeout and heartbeat interval. Some don't bother to restore the
original values again afterwards. So, add a helper to make it easier
to do this.

v2: Fix for platforms with no pre-emption capability.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/i915/gem_engine_topology.c | 46 ++++++++++++++++++++++++++++++++++
 lib/i915/gem_engine_topology.h |  9 +++++++
 2 files changed, 55 insertions(+)

diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
index 729f42b0a..bd12d0bc9 100644
--- a/lib/i915/gem_engine_topology.c
+++ b/lib/i915/gem_engine_topology.c
@@ -488,6 +488,52 @@ int gem_engine_property_printf(int i915, const char *engine, const char *attr,
 	return ret;
 }
 
+/* Ensure fast hang detection */
+void gem_engine_properties_configure(int fd, struct gem_engine_properties *params)
+{
+	int ret;
+	struct gem_engine_properties write = *params;
+
+	ret = gem_engine_property_scanf(fd, write.engine->name,
+					"heartbeat_interval_ms",
+					"%d", &params->heartbeat_interval);
+	igt_assert_eq(ret, 1);
+
+	ret = gem_engine_property_printf(fd, write.engine->name,
+					 "heartbeat_interval_ms", "%d",
+					 write.heartbeat_interval);
+	igt_assert_lt(0, ret);
+
+	if (gem_scheduler_has_preemption(fd)) {
+		ret = gem_engine_property_scanf(fd, write.engine->name,
+						"preempt_timeout_ms",
+						"%d", &params->preempt_timeout);
+		igt_assert_eq(ret, 1);
+
+		ret = gem_engine_property_printf(fd, write.engine->name,
+						 "preempt_timeout_ms", "%d",
+						 write.preempt_timeout);
+		igt_assert_lt(0, ret);
+	}
+}
+
+void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved)
+{
+	int ret;
+
+	ret = gem_engine_property_printf(fd, saved->engine->name,
+					 "heartbeat_interval_ms", "%d",
+					 saved->heartbeat_interval);
+	igt_assert_lt(0, ret);
+
+	if (gem_scheduler_has_preemption(fd)) {
+		ret = gem_engine_property_printf(fd, saved->engine->name,
+						 "preempt_timeout_ms", "%d",
+						 saved->preempt_timeout);
+		igt_assert_lt(0, ret);
+	}
+}
+
 uint32_t gem_engine_mmio_base(int i915, const char *engine)
 {
 	unsigned int mmio = 0;
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index 4cfab560b..b413aa8ab 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -115,6 +115,15 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags);
 	     ((e__) = intel_get_current_physical_engine(&i__##e__)); \
 	     intel_next_engine(&i__##e__))
 
+struct gem_engine_properties {
+	const struct intel_execution_engine2 *engine;
+	int preempt_timeout;
+	int heartbeat_interval;
+};
+
+void gem_engine_properties_configure(int fd, struct gem_engine_properties *params);
+void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved);
+
 __attribute__((format(scanf, 4, 5)))
 int gem_engine_property_scanf(int i915, const char *engine, const char *attr,
 			      const char *fmt, ...);
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 13/15] lib/i915: Add helper for non-destructive engine property updates
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Various tests want to configure engine properties such as pre-emption
timeout and heartbeat interval. Some don't bother to restore the
original values again afterwards. So, add a helper to make it easier
to do this.

v2: Fix for platforms with no pre-emption capability.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/i915/gem_engine_topology.c | 46 ++++++++++++++++++++++++++++++++++
 lib/i915/gem_engine_topology.h |  9 +++++++
 2 files changed, 55 insertions(+)

diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
index 729f42b0a..bd12d0bc9 100644
--- a/lib/i915/gem_engine_topology.c
+++ b/lib/i915/gem_engine_topology.c
@@ -488,6 +488,52 @@ int gem_engine_property_printf(int i915, const char *engine, const char *attr,
 	return ret;
 }
 
+/* Ensure fast hang detection */
+void gem_engine_properties_configure(int fd, struct gem_engine_properties *params)
+{
+	int ret;
+	struct gem_engine_properties write = *params;
+
+	ret = gem_engine_property_scanf(fd, write.engine->name,
+					"heartbeat_interval_ms",
+					"%d", &params->heartbeat_interval);
+	igt_assert_eq(ret, 1);
+
+	ret = gem_engine_property_printf(fd, write.engine->name,
+					 "heartbeat_interval_ms", "%d",
+					 write.heartbeat_interval);
+	igt_assert_lt(0, ret);
+
+	if (gem_scheduler_has_preemption(fd)) {
+		ret = gem_engine_property_scanf(fd, write.engine->name,
+						"preempt_timeout_ms",
+						"%d", &params->preempt_timeout);
+		igt_assert_eq(ret, 1);
+
+		ret = gem_engine_property_printf(fd, write.engine->name,
+						 "preempt_timeout_ms", "%d",
+						 write.preempt_timeout);
+		igt_assert_lt(0, ret);
+	}
+}
+
+void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved)
+{
+	int ret;
+
+	ret = gem_engine_property_printf(fd, saved->engine->name,
+					 "heartbeat_interval_ms", "%d",
+					 saved->heartbeat_interval);
+	igt_assert_lt(0, ret);
+
+	if (gem_scheduler_has_preemption(fd)) {
+		ret = gem_engine_property_printf(fd, saved->engine->name,
+						 "preempt_timeout_ms", "%d",
+						 saved->preempt_timeout);
+		igt_assert_lt(0, ret);
+	}
+}
+
 uint32_t gem_engine_mmio_base(int i915, const char *engine)
 {
 	unsigned int mmio = 0;
diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
index 4cfab560b..b413aa8ab 100644
--- a/lib/i915/gem_engine_topology.h
+++ b/lib/i915/gem_engine_topology.h
@@ -115,6 +115,15 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags);
 	     ((e__) = intel_get_current_physical_engine(&i__##e__)); \
 	     intel_next_engine(&i__##e__))
 
+struct gem_engine_properties {
+	const struct intel_execution_engine2 *engine;
+	int preempt_timeout;
+	int heartbeat_interval;
+};
+
+void gem_engine_properties_configure(int fd, struct gem_engine_properties *params);
+void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved);
+
 __attribute__((format(scanf, 4, 5)))
 int gem_engine_property_scanf(int i915, const char *engine, const char *attr,
 			      const char *fmt, ...);
-- 
2.25.1

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

* [Intel-gfx] [PATCH v3 i-g-t 14/15] tests/i915/i915_hangman: Configure engine properties for quicker hangs
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (13 preceding siblings ...)
  (?)
@ 2022-01-13 19:59 ` John.C.Harrison
  2022-01-13 22:38   ` Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Some platforms have very long timeouts configured for some engines.
Some have them disabled completely. That makes for a very slow (or
broken) hangman test. So explicitly configure the engines to have
reasonable settings first.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 567eb71ee..1a2b2cf7a 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -500,8 +500,12 @@ igt_main
 {
 	const intel_ctx_t *ctx;
 	igt_hang_t hang = {};
+	struct gem_engine_properties saved_params[GEM_MAX_ENGINES];
+	int num_engines = 0;
 
 	igt_fixture {
+		const struct intel_execution_engine2 *e;
+
 		device = drm_open_driver(DRIVER_INTEL);
 		igt_require_gem(device);
 
@@ -515,6 +519,13 @@ igt_main
 		igt_require(has_error_state(sysfs));
 
 		gem_require_mmap_wc(device);
+
+		for_each_physical_engine(device, e) {
+			saved_params[num_engines].engine = e;
+			saved_params[num_engines].preempt_timeout = 500;
+			saved_params[num_engines].heartbeat_interval = 1000;
+			gem_engine_properties_configure(device, saved_params + num_engines++);
+		}
 	}
 
 	igt_describe("Basic error capture");
@@ -546,6 +557,11 @@ igt_main
 	do_tests("engine", "engine", ctx);
 
 	igt_fixture {
+		int i;
+
+		for (i = 0; i < num_engines; i++)
+			gem_engine_properties_restore(device, saved_params + i);
+
 		igt_disallow_hang(device, hang);
 		intel_ctx_destroy(device, ctx);
 		close(device);
-- 
2.25.1


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

* [Intel-gfx] [PATCH v3 i-g-t 15/15] tests/i915/gem_exec_capture: Restore engines
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
@ 2022-01-13 19:59   ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The test was updated some engine properties but not restoring them
afterwards. That would leave the system in a non-default state which
could potentially affect subsequent tests. Fix it by using the new
save/restore engine properties helper functions.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/gem_exec_capture.c | 37 ++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c
index 9beb36fc7..51db07c41 100644
--- a/tests/i915/gem_exec_capture.c
+++ b/tests/i915/gem_exec_capture.c
@@ -209,14 +209,21 @@ static int check_error_state(int dir, struct offset *obj_offsets, int obj_count,
 	return blobs;
 }
 
-static void configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
+static struct gem_engine_properties
+configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
 {
+	struct gem_engine_properties props;
+
 	/* Ensure fast hang detection */
-	gem_engine_property_printf(fd, e->name, "preempt_timeout_ms", "%d", 250);
-	gem_engine_property_printf(fd, e->name, "heartbeat_interval_ms", "%d", 500);
+	props.engine = e;
+	props.preempt_timeout = 250;
+	props.heartbeat_interval = 500;
+	gem_engine_properties_configure(fd, &props);
 
 	/* Allow engine based resets and disable banning */
 	igt_allow_hang(fd, ctxt_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+
+	return props;
 }
 
 static bool fence_busy(int fence)
@@ -256,8 +263,9 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	uint32_t *batch, *seqno;
 	struct offset offset;
 	int i, fence_out;
+	struct gem_engine_properties saved_engine;
 
-	configure_hangs(fd, e, ctx->id);
+	saved_engine = configure_hangs(fd, e, ctx->id);
 
 	memset(obj, 0, sizeof(obj));
 	obj[SCRATCH].handle = gem_create_in_memory_regions(fd, 4096, region);
@@ -371,6 +379,8 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	gem_close(fd, obj[BATCH].handle);
 	gem_close(fd, obj[NOCAPTURE].handle);
 	gem_close(fd, obj[SCRATCH].handle);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static void capture(int fd, int dir, const intel_ctx_t *ctx,
@@ -417,8 +427,9 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	uint32_t *batch, *seqno;
 	struct offset *offsets;
 	int i, fence_out;
+	struct gem_engine_properties saved_engine;
 
-	configure_hangs(fd, e, ctx->id);
+	saved_engine = configure_hangs(fd, e, ctx->id);
 
 	offsets = calloc(count, sizeof(*offsets));
 	igt_assert(offsets);
@@ -559,10 +570,12 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 
 	qsort(offsets, count, sizeof(*offsets), cmp);
 	igt_assert(offsets[0].addr <= offsets[count-1].addr);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 	return offsets;
 }
 
-#define find_first_available_engine(fd, ctx, e) \
+#define find_first_available_engine(fd, ctx, e, saved) \
 	do { \
 		ctx = intel_ctx_create_all_physical(fd); \
 		igt_assert(ctx); \
@@ -570,7 +583,7 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 			for_each_if(gem_class_can_store_dword(fd, e->class)) \
 				break; \
 		igt_assert(e); \
-		configure_hangs(fd, e, ctx->id); \
+		saved = configure_hangs(fd, e, ctx->id); \
 	} while(0)
 
 static void many(int fd, int dir, uint64_t size, unsigned int flags)
@@ -580,8 +593,9 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
 	uint64_t ram, gtt, ahnd;
 	unsigned long count, blobs;
 	struct offset *offsets;
+	struct gem_engine_properties saved_engine;
 
-	find_first_available_engine(fd, ctx, e);
+	find_first_available_engine(fd, ctx, e, saved_engine);
 
 	gtt = gem_aperture_size(fd) / size;
 	ram = (intel_get_avail_ram_mb() << 20) / size;
@@ -602,6 +616,8 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
 
 	free(offsets);
 	put_ahnd(ahnd);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static void prioinv(int fd, int dir, const intel_ctx_t *ctx,
@@ -697,8 +713,9 @@ static void userptr(int fd, int dir)
 	void *ptr;
 	int obj_size = 4096;
 	uint32_t system_region = INTEL_MEMORY_REGION_ID(I915_SYSTEM_MEMORY, 0);
+	struct gem_engine_properties saved_engine;
 
-	find_first_available_engine(fd, ctx, e);
+	find_first_available_engine(fd, ctx, e, saved_engine);
 
 	igt_assert(posix_memalign(&ptr, obj_size, obj_size) == 0);
 	memset(ptr, 0, obj_size);
@@ -710,6 +727,8 @@ static void userptr(int fd, int dir)
 	gem_close(fd, handle);
 	put_ahnd(ahnd);
 	free(ptr);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static bool has_capture(int fd)
-- 
2.25.1


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

* [igt-dev] [PATCH v3 i-g-t 15/15] tests/i915/gem_exec_capture: Restore engines
@ 2022-01-13 19:59   ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 19:59 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The test was updated some engine properties but not restoring them
afterwards. That would leave the system in a non-default state which
could potentially affect subsequent tests. Fix it by using the new
save/restore engine properties helper functions.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/gem_exec_capture.c | 37 ++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c
index 9beb36fc7..51db07c41 100644
--- a/tests/i915/gem_exec_capture.c
+++ b/tests/i915/gem_exec_capture.c
@@ -209,14 +209,21 @@ static int check_error_state(int dir, struct offset *obj_offsets, int obj_count,
 	return blobs;
 }
 
-static void configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
+static struct gem_engine_properties
+configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
 {
+	struct gem_engine_properties props;
+
 	/* Ensure fast hang detection */
-	gem_engine_property_printf(fd, e->name, "preempt_timeout_ms", "%d", 250);
-	gem_engine_property_printf(fd, e->name, "heartbeat_interval_ms", "%d", 500);
+	props.engine = e;
+	props.preempt_timeout = 250;
+	props.heartbeat_interval = 500;
+	gem_engine_properties_configure(fd, &props);
 
 	/* Allow engine based resets and disable banning */
 	igt_allow_hang(fd, ctxt_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
+
+	return props;
 }
 
 static bool fence_busy(int fence)
@@ -256,8 +263,9 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	uint32_t *batch, *seqno;
 	struct offset offset;
 	int i, fence_out;
+	struct gem_engine_properties saved_engine;
 
-	configure_hangs(fd, e, ctx->id);
+	saved_engine = configure_hangs(fd, e, ctx->id);
 
 	memset(obj, 0, sizeof(obj));
 	obj[SCRATCH].handle = gem_create_in_memory_regions(fd, 4096, region);
@@ -371,6 +379,8 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	gem_close(fd, obj[BATCH].handle);
 	gem_close(fd, obj[NOCAPTURE].handle);
 	gem_close(fd, obj[SCRATCH].handle);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static void capture(int fd, int dir, const intel_ctx_t *ctx,
@@ -417,8 +427,9 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 	uint32_t *batch, *seqno;
 	struct offset *offsets;
 	int i, fence_out;
+	struct gem_engine_properties saved_engine;
 
-	configure_hangs(fd, e, ctx->id);
+	saved_engine = configure_hangs(fd, e, ctx->id);
 
 	offsets = calloc(count, sizeof(*offsets));
 	igt_assert(offsets);
@@ -559,10 +570,12 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 
 	qsort(offsets, count, sizeof(*offsets), cmp);
 	igt_assert(offsets[0].addr <= offsets[count-1].addr);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 	return offsets;
 }
 
-#define find_first_available_engine(fd, ctx, e) \
+#define find_first_available_engine(fd, ctx, e, saved) \
 	do { \
 		ctx = intel_ctx_create_all_physical(fd); \
 		igt_assert(ctx); \
@@ -570,7 +583,7 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
 			for_each_if(gem_class_can_store_dword(fd, e->class)) \
 				break; \
 		igt_assert(e); \
-		configure_hangs(fd, e, ctx->id); \
+		saved = configure_hangs(fd, e, ctx->id); \
 	} while(0)
 
 static void many(int fd, int dir, uint64_t size, unsigned int flags)
@@ -580,8 +593,9 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
 	uint64_t ram, gtt, ahnd;
 	unsigned long count, blobs;
 	struct offset *offsets;
+	struct gem_engine_properties saved_engine;
 
-	find_first_available_engine(fd, ctx, e);
+	find_first_available_engine(fd, ctx, e, saved_engine);
 
 	gtt = gem_aperture_size(fd) / size;
 	ram = (intel_get_avail_ram_mb() << 20) / size;
@@ -602,6 +616,8 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
 
 	free(offsets);
 	put_ahnd(ahnd);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static void prioinv(int fd, int dir, const intel_ctx_t *ctx,
@@ -697,8 +713,9 @@ static void userptr(int fd, int dir)
 	void *ptr;
 	int obj_size = 4096;
 	uint32_t system_region = INTEL_MEMORY_REGION_ID(I915_SYSTEM_MEMORY, 0);
+	struct gem_engine_properties saved_engine;
 
-	find_first_available_engine(fd, ctx, e);
+	find_first_available_engine(fd, ctx, e, saved_engine);
 
 	igt_assert(posix_memalign(&ptr, obj_size, obj_size) == 0);
 	memset(ptr, 0, obj_size);
@@ -710,6 +727,8 @@ static void userptr(int fd, int dir)
 	gem_close(fd, handle);
 	put_ahnd(ahnd);
 	free(ptr);
+
+	gem_engine_properties_restore(fd, &saved_engine);
 }
 
 static bool has_capture(int fd)
-- 
2.25.1

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

* Re: [Intel-gfx] [PATCH v3 i-g-t 06/15] tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated
  2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 06/15] tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated John.C.Harrison
@ 2022-01-13 20:00     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:00 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:38AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The hangman framework sets up a context that is valid for all engines
> and has things like banning disabled. The 'unterminated' test then
> ignores it and uses the default context. Fix that.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 354769f39..6656b3fcd 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -347,6 +347,7 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
>  	memset(&execbuf, 0, sizeof(execbuf));
>  	execbuf.buffers_ptr = (uintptr_t)&gem_exec;
>  	execbuf.buffer_count = 1;
> +	execbuf.rsvd1 = ctx->id;
>  
>  	gem_execbuf(device, &execbuf);
>  	if (gem_wait(device, handle, &timeout_ns) != 0) {
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [Intel-gfx] [PATCH v3 i-g-t 06/15] tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated
@ 2022-01-13 20:00     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:00 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:38AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The hangman framework sets up a context that is valid for all engines
> and has things like banning disabled. The 'unterminated' test then
> ignores it and uses the default context. Fix that.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 354769f39..6656b3fcd 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -347,6 +347,7 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
>  	memset(&execbuf, 0, sizeof(execbuf));
>  	execbuf.buffers_ptr = (uintptr_t)&gem_exec;
>  	execbuf.buffer_count = 1;
> +	execbuf.rsvd1 = ctx->id;
>  
>  	gem_execbuf(device, &execbuf);
>  	if (gem_wait(device, handle, &timeout_ns) != 0) {
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
  (?)
@ 2022-01-13 20:10   ` Matthew Brost
  2022-01-13 20:27       ` John Harrison
  -1 siblings, 1 reply; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:10 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> A lot of tests use almost identical code for creating a batch buffer
> which does a single write to memory and another is about to be added.
> Instead, move the most generic version into a common helper function.
> Unfortunately, the other instances are all subtly different enough to
> make it not so trivial to try to use the helper. It could be done but
> it is unclear if it is worth the effort at this point. This patch
> proves the concept, if people like it enough then it can be extended.
> 
> v2: Fix up object address vs store offset confusion (with help from
> Zbigniew K).
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
>  lib/igt_store.h             | 12 +++++
>  lib/meson.build             |  1 +
>  tests/i915/gem_exec_fence.c | 77 ++---------------------------
>  tests/i915/i915_hangman.c   |  1 +
>  5 files changed, 115 insertions(+), 72 deletions(-)
>  create mode 100644 lib/igt_store.c
>  create mode 100644 lib/igt_store.h
> 
> diff --git a/lib/igt_store.c b/lib/igt_store.c
> new file mode 100644
> index 000000000..42c888b55
> --- /dev/null
> +++ b/lib/igt_store.c
> @@ -0,0 +1,96 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include "i915/gem_create.h"
> +#include "igt_core.h"
> +#include "drmtest.h"
> +#include "igt_store.h"
> +#include "intel_chipset.h"
> +#include "intel_reg.h"
> +#include "ioctl_wrappers.h"
> +#include "lib/intel_allocator.h"
> +
> +/**
> + * SECTION:igt_store_word
> + * @short_description: Library for writing a value to memory
> + * @title: StoreWord
> + * @include: igt.h
> + *
> + * A lot of igt testcases need some mechanism for writing a value to memory
> + * as a test that a batch buffer has executed.
> + *
> + * NB: Requires master for STORE_DWORD on gen4/5.
> + */
> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> +		    const struct intel_execution_engine2 *e,
> +		    int fence, uint32_t target_handle,
> +		    uint64_t target_gpu_addr,
> +		    uint64_t store_offset, uint32_t store_value)
> +{
> +	const int SCRATCH = 0;
> +	const int BATCH = 1;
> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> +	struct drm_i915_gem_exec_object2 obj[2];
> +	struct drm_i915_gem_relocation_entry reloc;
> +	struct drm_i915_gem_execbuffer2 execbuf;
> +	uint32_t batch[16], delta;
> +	uint64_t bb_offset;
> +	int i;
> +
> +	memset(&execbuf, 0, sizeof(execbuf));
> +	execbuf.buffers_ptr = to_user_pointer(obj);
> +	execbuf.buffer_count = ARRAY_SIZE(obj);
> +	execbuf.flags = e->flags;
> +	execbuf.rsvd1 = ctx->id;
> +	if (fence != -1) {
> +		execbuf.flags |= I915_EXEC_FENCE_IN;
> +		execbuf.rsvd2 = fence;
> +	}
> +	if (gen < 6)
> +		execbuf.flags |= I915_EXEC_SECURE;
> +
> +	memset(obj, 0, sizeof(obj));
> +	obj[SCRATCH].handle = target_handle;
> +
> +	obj[BATCH].handle = gem_create(fd, 4096);
> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> +	memset(&reloc, 0, sizeof(reloc));
> +
> +	i = 0;
> +	delta = sizeof(uint32_t) * store_offset;

Can't this overflow the delta as store_offset is a u64?

> +	if (!ahnd) {
> +		reloc.target_handle = obj[SCRATCH].handle;
> +		reloc.presumed_offset = -1;
> +		reloc.offset = sizeof(uint32_t) * (i + 1);
> +		reloc.delta = delta;
> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> +	} else {
> +		obj[SCRATCH].offset = target_gpu_addr;
> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> +		obj[BATCH].offset = bb_offset;
> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> +	}
> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> +	if (gen >= 8) {
> +		batch[++i] = target_gpu_addr + delta;
> +		batch[++i] = (target_gpu_addr + delta) >> 32;

This is different from the previous code, presumably this is fixing a
bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
32 bits?

Matt

> +	} else if (gen >= 4) {
> +		batch[++i] = 0;
> +		batch[++i] = delta;
> +		reloc.offset += sizeof(uint32_t);
> +	} else {
> +		batch[i]--;
> +		batch[++i] = delta;
> +	}
> +	batch[++i] = store_value;
> +	batch[++i] = MI_BATCH_BUFFER_END;
> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> +	gem_execbuf(fd, &execbuf);
> +	gem_close(fd, obj[BATCH].handle);
> +	put_offset(ahnd, obj[BATCH].handle);
> +}
> diff --git a/lib/igt_store.h b/lib/igt_store.h
> new file mode 100644
> index 000000000..5c6c8263c
> --- /dev/null
> +++ b/lib/igt_store.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include "igt_gt.h"
> +
> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> +		    const struct intel_execution_engine2 *e,
> +		    int fence, uint32_t target_handle,
> +		    uint64_t target_gpu_addr,
> +		    uint64_t store_offset, uint32_t store_value);
> diff --git a/lib/meson.build b/lib/meson.build
> index b9568a71b..3e43316d1 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -72,6 +72,7 @@ lib_sources = [
>  	'igt_map.c',
>  	'igt_pm.c',
>  	'igt_dummyload.c',
> +	'igt_store.c',
>  	'uwildmat/uwildmat.c',
>  	'igt_kmod.c',
>  	'igt_panfrost.c',
> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
> index 9a6336ce9..196236b27 100644
> --- a/tests/i915/gem_exec_fence.c
> +++ b/tests/i915/gem_exec_fence.c
> @@ -28,6 +28,7 @@
>  #include "i915/gem.h"
>  #include "i915/gem_create.h"
>  #include "igt.h"
> +#include "igt_store.h"
>  #include "igt_syncobj.h"
>  #include "igt_sysfs.h"
>  #include "igt_vgem.h"
> @@ -57,74 +58,6 @@ struct sync_merge_data {
>  #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>  #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>  
> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> -		  const struct intel_execution_engine2 *e,
> -		  int fence, uint32_t target, uint64_t target_offset,
> -		  unsigned offset_value)
> -{
> -	const int SCRATCH = 0;
> -	const int BATCH = 1;
> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> -	struct drm_i915_gem_exec_object2 obj[2];
> -	struct drm_i915_gem_relocation_entry reloc;
> -	struct drm_i915_gem_execbuffer2 execbuf;
> -	uint32_t batch[16], delta;
> -	uint64_t bb_offset;
> -	int i;
> -
> -	memset(&execbuf, 0, sizeof(execbuf));
> -	execbuf.buffers_ptr = to_user_pointer(obj);
> -	execbuf.buffer_count = 2;
> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
> -	execbuf.rsvd1 = ctx->id;
> -	execbuf.rsvd2 = fence;
> -	if (gen < 6)
> -		execbuf.flags |= I915_EXEC_SECURE;
> -
> -	memset(obj, 0, sizeof(obj));
> -	obj[SCRATCH].handle = target;
> -
> -	obj[BATCH].handle = gem_create(fd, 4096);
> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> -	memset(&reloc, 0, sizeof(reloc));
> -
> -	i = 0;
> -	delta = sizeof(uint32_t) * offset_value;
> -	if (!ahnd) {
> -		reloc.target_handle = obj[SCRATCH].handle;
> -		reloc.presumed_offset = -1;
> -		reloc.offset = sizeof(uint32_t) * (i + 1);
> -		reloc.delta = delta;
> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> -	} else {
> -		obj[SCRATCH].offset = target_offset;
> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> -		obj[BATCH].offset = bb_offset;
> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> -	}
> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> -	if (gen >= 8) {
> -		batch[++i] = target_offset + delta;
> -		batch[++i] = target_offset >> 32;
> -	} else if (gen >= 4) {
> -		batch[++i] = 0;
> -		batch[++i] = delta;
> -		reloc.offset += sizeof(uint32_t);
> -	} else {
> -		batch[i]--;
> -		batch[++i] = delta;
> -	}
> -	batch[++i] = offset_value;
> -	batch[++i] = MI_BATCH_BUFFER_END;
> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> -	gem_execbuf(fd, &execbuf);
> -	gem_close(fd, obj[BATCH].handle);
> -	put_offset(ahnd, obj[BATCH].handle);
> -}
> -
>  static bool fence_busy(int fence)
>  {
>  	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>  			continue;
>  
>  		if (flags & NONBLOCK) {
> -			store(fd, ahnd, ctx, e2, spin->out_fence,
> -			      scratch, scratch_offset, i);
> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> +				       scratch, scratch_offset, i, i);
>  		} else {
>  			igt_fork(child, 1) {
>  				ahnd = get_reloc_ahnd(fd, ctx->id);
> -				store(fd, ahnd, ctx, e2, spin->out_fence,
> -				      scratch, scratch_offset, i);
> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> +					       scratch, scratch_offset, i, i);
>  				put_ahnd(ahnd);
>  			}
>  		}
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 6656b3fcd..5a0c9497c 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -36,6 +36,7 @@
>  #include "i915/gem.h"
>  #include "i915/gem_create.h"
>  #include "igt.h"
> +#include "igt_store.h"
>  #include "igt_sysfs.h"
>  #include "igt_debugfs.h"
>  #include "sw_sync.h"
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [PATCH v3 i-g-t 08/15] tests/i915/i915_hangman: Add alive-ness test after error capture
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 20:18     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:18 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:40AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Added a an extra step to the i915_hangman tests to check that the
> system is still alive after the hang and recovery. This submits a
> simple batch to each engine which does a write to memory and checks
> that the write occurred.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Looks good to me but can't help but think this could be a library
function as I really doubt this is the only test where at the end of the
test we want to verify all engines are alive. Something to keep an eye /
do in a follow up.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 5a0c9497c..918418760 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -48,8 +48,57 @@
>  static int device = -1;
>  static int sysfs = -1;
>  
> +#define OFFSET_ALIVE	10
> +
>  IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
>  
> +static void check_alive(void)
> +{
> +	const struct intel_execution_engine2 *engine;
> +	const intel_ctx_t *ctx;
> +	uint32_t scratch, *out;
> +	int fd, i = 0;
> +	uint64_t ahnd, scratch_addr;
> +
> +	fd = drm_open_driver(DRIVER_INTEL);
> +	igt_require(gem_class_can_store_dword(fd, 0));
> +
> +	ctx = intel_ctx_create_all_physical(fd);
> +	ahnd = get_reloc_ahnd(fd, ctx->id);
> +	scratch = gem_create(fd, 4096);
> +	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
> +	out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
> +	gem_set_domain(fd, scratch,
> +			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +
> +	for_each_physical_engine(fd, engine) {
> +		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
> +		i++;
> +	}
> +
> +	i = 0;
> +	for_each_ctx_engine(fd, ctx, engine) {
> +		if (!gem_class_can_store_dword(fd, engine->class))
> +			continue;
> +
> +		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
> +		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
> +			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
> +		i++;
> +	}
> +
> +	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
> +
> +	while (i--)
> +		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
> +
> +	munmap(out, 4096);
> +	gem_close(fd, scratch);
> +	put_ahnd(ahnd);
> +	intel_ctx_destroy(fd, ctx);
> +	close(fd);
> +}
> +
>  static bool has_error_state(int dir)
>  {
>  	bool result;
> @@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_error_state(e->name, offset, batch);
>  	munmap(batch, 4096);
>  	put_ahnd(ahnd);
> +
> +	check_alive();
>  }
>  
>  static void
> @@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		put_ahnd(ahndN);
>  	}
>  	put_ahnd(ahnd);
> +
> +	check_alive();
>  }
>  
>  static int hang_count;
> @@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
>  
>  	/* Did it work? */
>  	igt_assert(hang_count == 1);
> +
> +	check_alive();
>  }
>  
>  /* This test covers the case where we end up in an uninitialised area of the
> @@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
>  		igt_force_gpu_reset(device);
>  		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
>  	}
> +
> +	check_alive();
>  }
>  
>  static void do_tests(const char *name, const char *prefix,
> @@ -433,6 +490,8 @@ igt_main
>  		igt_assert(sysfs != -1);
>  
>  		igt_require(has_error_state(sysfs));
> +
> +		gem_require_mmap_wc(device);
>  	}
>  
>  	igt_describe("Basic error capture");
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [Intel-gfx] [PATCH v3 i-g-t 08/15] tests/i915/i915_hangman: Add alive-ness test after error capture
@ 2022-01-13 20:18     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:18 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:40AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Added a an extra step to the i915_hangman tests to check that the
> system is still alive after the hang and recovery. This submits a
> simple batch to each engine which does a write to memory and checks
> that the write occurred.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Looks good to me but can't help but think this could be a library
function as I really doubt this is the only test where at the end of the
test we want to verify all engines are alive. Something to keep an eye /
do in a follow up.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 5a0c9497c..918418760 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -48,8 +48,57 @@
>  static int device = -1;
>  static int sysfs = -1;
>  
> +#define OFFSET_ALIVE	10
> +
>  IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
>  
> +static void check_alive(void)
> +{
> +	const struct intel_execution_engine2 *engine;
> +	const intel_ctx_t *ctx;
> +	uint32_t scratch, *out;
> +	int fd, i = 0;
> +	uint64_t ahnd, scratch_addr;
> +
> +	fd = drm_open_driver(DRIVER_INTEL);
> +	igt_require(gem_class_can_store_dword(fd, 0));
> +
> +	ctx = intel_ctx_create_all_physical(fd);
> +	ahnd = get_reloc_ahnd(fd, ctx->id);
> +	scratch = gem_create(fd, 4096);
> +	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
> +	out = gem_mmap__wc(fd, scratch, 0, 4096, PROT_WRITE);
> +	gem_set_domain(fd, scratch,
> +			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
> +
> +	for_each_physical_engine(fd, engine) {
> +		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
> +		i++;
> +	}
> +
> +	i = 0;
> +	for_each_ctx_engine(fd, ctx, engine) {
> +		if (!gem_class_can_store_dword(fd, engine->class))
> +			continue;
> +
> +		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
> +		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
> +			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
> +		i++;
> +	}
> +
> +	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
> +
> +	while (i--)
> +		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
> +
> +	munmap(out, 4096);
> +	gem_close(fd, scratch);
> +	put_ahnd(ahnd);
> +	intel_ctx_destroy(fd, ctx);
> +	close(fd);
> +}
> +
>  static bool has_error_state(int dir)
>  {
>  	bool result;
> @@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_error_state(e->name, offset, batch);
>  	munmap(batch, 4096);
>  	put_ahnd(ahnd);
> +
> +	check_alive();
>  }
>  
>  static void
> @@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		put_ahnd(ahndN);
>  	}
>  	put_ahnd(ahnd);
> +
> +	check_alive();
>  }
>  
>  static int hang_count;
> @@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
>  
>  	/* Did it work? */
>  	igt_assert(hang_count == 1);
> +
> +	check_alive();
>  }
>  
>  /* This test covers the case where we end up in an uninitialised area of the
> @@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
>  		igt_force_gpu_reset(device);
>  		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
>  	}
> +
> +	check_alive();
>  }
>  
>  static void do_tests(const char *name, const char *prefix,
> @@ -433,6 +490,8 @@ igt_main
>  		igt_assert(sysfs != -1);
>  
>  		igt_require(has_error_state(sysfs));
> +
> +		gem_require_mmap_wc(device);
>  	}
>  
>  	igt_describe("Basic error capture");
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
  2022-01-13 20:27       ` John Harrison
@ 2022-01-13 20:23         ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:23 UTC (permalink / raw)
  To: John Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 12:27:00PM -0800, John Harrison wrote:
> On 1/13/2022 12:10, Matthew Brost wrote:
> > On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
> > > From: John Harrison <John.C.Harrison@Intel.com>
> > > 
> > > A lot of tests use almost identical code for creating a batch buffer
> > > which does a single write to memory and another is about to be added.
> > > Instead, move the most generic version into a common helper function.
> > > Unfortunately, the other instances are all subtly different enough to
> > > make it not so trivial to try to use the helper. It could be done but
> > > it is unclear if it is worth the effort at this point. This patch
> > > proves the concept, if people like it enough then it can be extended.
> > > 
> > > v2: Fix up object address vs store offset confusion (with help from
> > > Zbigniew K).
> > > 
> > > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > > ---
> > >   lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
> > >   lib/igt_store.h             | 12 +++++
> > >   lib/meson.build             |  1 +
> > >   tests/i915/gem_exec_fence.c | 77 ++---------------------------
> > >   tests/i915/i915_hangman.c   |  1 +
> > >   5 files changed, 115 insertions(+), 72 deletions(-)
> > >   create mode 100644 lib/igt_store.c
> > >   create mode 100644 lib/igt_store.h
> > > 
> > > diff --git a/lib/igt_store.c b/lib/igt_store.c
> > > new file mode 100644
> > > index 000000000..42c888b55
> > > --- /dev/null
> > > +++ b/lib/igt_store.c
> > > @@ -0,0 +1,96 @@
> > > +/* SPDX-License-Identifier: MIT */
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#include "i915/gem_create.h"
> > > +#include "igt_core.h"
> > > +#include "drmtest.h"
> > > +#include "igt_store.h"
> > > +#include "intel_chipset.h"
> > > +#include "intel_reg.h"
> > > +#include "ioctl_wrappers.h"
> > > +#include "lib/intel_allocator.h"
> > > +
> > > +/**
> > > + * SECTION:igt_store_word
> > > + * @short_description: Library for writing a value to memory
> > > + * @title: StoreWord
> > > + * @include: igt.h
> > > + *
> > > + * A lot of igt testcases need some mechanism for writing a value to memory
> > > + * as a test that a batch buffer has executed.
> > > + *
> > > + * NB: Requires master for STORE_DWORD on gen4/5.
> > > + */
> > > +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > +		    const struct intel_execution_engine2 *e,
> > > +		    int fence, uint32_t target_handle,
> > > +		    uint64_t target_gpu_addr,
> > > +		    uint64_t store_offset, uint32_t store_value)
> > > +{
> > > +	const int SCRATCH = 0;
> > > +	const int BATCH = 1;
> > > +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> > > +	struct drm_i915_gem_exec_object2 obj[2];
> > > +	struct drm_i915_gem_relocation_entry reloc;
> > > +	struct drm_i915_gem_execbuffer2 execbuf;
> > > +	uint32_t batch[16], delta;
> > > +	uint64_t bb_offset;
> > > +	int i;
> > > +
> > > +	memset(&execbuf, 0, sizeof(execbuf));
> > > +	execbuf.buffers_ptr = to_user_pointer(obj);
> > > +	execbuf.buffer_count = ARRAY_SIZE(obj);
> > > +	execbuf.flags = e->flags;
> > > +	execbuf.rsvd1 = ctx->id;
> > > +	if (fence != -1) {
> > > +		execbuf.flags |= I915_EXEC_FENCE_IN;
> > > +		execbuf.rsvd2 = fence;
> > > +	}
> > > +	if (gen < 6)
> > > +		execbuf.flags |= I915_EXEC_SECURE;
> > > +
> > > +	memset(obj, 0, sizeof(obj));
> > > +	obj[SCRATCH].handle = target_handle;
> > > +
> > > +	obj[BATCH].handle = gem_create(fd, 4096);
> > > +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> > > +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> > > +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> > > +	memset(&reloc, 0, sizeof(reloc));
> > > +
> > > +	i = 0;
> > > +	delta = sizeof(uint32_t) * store_offset;
> > Can't this overflow the delta as store_offset is a u64?
> Oops.
> 
> Yeah, this code was a right mess of data words being used as addresses and
> random copies supporting 64bit or only 32bit offsets. I believe it's
> currently fine as even platforms which can theoretically support >32bits
> don't actually use it. But yes, will repost with a 64bit version of delta.
> 
> > 
> > > +	if (!ahnd) {
> > > +		reloc.target_handle = obj[SCRATCH].handle;
> > > +		reloc.presumed_offset = -1;
> > > +		reloc.offset = sizeof(uint32_t) * (i + 1);

Then just be safe, probably assert the upper 32 bits of delta are clear too.

Matt

> > > +		reloc.delta = delta;
> > > +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> > > +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> > > +	} else {
> > > +		obj[SCRATCH].offset = target_gpu_addr;
> > > +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> > > +		obj[BATCH].offset = bb_offset;
> > > +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> > > +	}
> > > +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> > > +	if (gen >= 8) {
> > > +		batch[++i] = target_gpu_addr + delta;
> > > +		batch[++i] = (target_gpu_addr + delta) >> 32;
> > This is different from the previous code, presumably this is fixing a
> > bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
> > 32 bits?
> > 
> > Matt
> Yeah, some copies of this code were definitely broken for >32bit addresses.
> 
> John.
> 
> > 
> > > +	} else if (gen >= 4) {
> > > +		batch[++i] = 0;
> > > +		batch[++i] = delta;
> > > +		reloc.offset += sizeof(uint32_t);
> > > +	} else {
> > > +		batch[i]--;
> > > +		batch[++i] = delta;
> > > +	}
> > > +	batch[++i] = store_value;
> > > +	batch[++i] = MI_BATCH_BUFFER_END;
> > > +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> > > +	gem_execbuf(fd, &execbuf);
> > > +	gem_close(fd, obj[BATCH].handle);
> > > +	put_offset(ahnd, obj[BATCH].handle);
> > > +}
> > > diff --git a/lib/igt_store.h b/lib/igt_store.h
> > > new file mode 100644
> > > index 000000000..5c6c8263c
> > > --- /dev/null
> > > +++ b/lib/igt_store.h
> > > @@ -0,0 +1,12 @@
> > > +/* SPDX-License-Identifier: MIT */
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#include "igt_gt.h"
> > > +
> > > +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > +		    const struct intel_execution_engine2 *e,
> > > +		    int fence, uint32_t target_handle,
> > > +		    uint64_t target_gpu_addr,
> > > +		    uint64_t store_offset, uint32_t store_value);
> > > diff --git a/lib/meson.build b/lib/meson.build
> > > index b9568a71b..3e43316d1 100644
> > > --- a/lib/meson.build
> > > +++ b/lib/meson.build
> > > @@ -72,6 +72,7 @@ lib_sources = [
> > >   	'igt_map.c',
> > >   	'igt_pm.c',
> > >   	'igt_dummyload.c',
> > > +	'igt_store.c',
> > >   	'uwildmat/uwildmat.c',
> > >   	'igt_kmod.c',
> > >   	'igt_panfrost.c',
> > > diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
> > > index 9a6336ce9..196236b27 100644
> > > --- a/tests/i915/gem_exec_fence.c
> > > +++ b/tests/i915/gem_exec_fence.c
> > > @@ -28,6 +28,7 @@
> > >   #include "i915/gem.h"
> > >   #include "i915/gem_create.h"
> > >   #include "igt.h"
> > > +#include "igt_store.h"
> > >   #include "igt_syncobj.h"
> > >   #include "igt_sysfs.h"
> > >   #include "igt_vgem.h"
> > > @@ -57,74 +58,6 @@ struct sync_merge_data {
> > >   #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
> > >   #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
> > > -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > -		  const struct intel_execution_engine2 *e,
> > > -		  int fence, uint32_t target, uint64_t target_offset,
> > > -		  unsigned offset_value)
> > > -{
> > > -	const int SCRATCH = 0;
> > > -	const int BATCH = 1;
> > > -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> > > -	struct drm_i915_gem_exec_object2 obj[2];
> > > -	struct drm_i915_gem_relocation_entry reloc;
> > > -	struct drm_i915_gem_execbuffer2 execbuf;
> > > -	uint32_t batch[16], delta;
> > > -	uint64_t bb_offset;
> > > -	int i;
> > > -
> > > -	memset(&execbuf, 0, sizeof(execbuf));
> > > -	execbuf.buffers_ptr = to_user_pointer(obj);
> > > -	execbuf.buffer_count = 2;
> > > -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
> > > -	execbuf.rsvd1 = ctx->id;
> > > -	execbuf.rsvd2 = fence;
> > > -	if (gen < 6)
> > > -		execbuf.flags |= I915_EXEC_SECURE;
> > > -
> > > -	memset(obj, 0, sizeof(obj));
> > > -	obj[SCRATCH].handle = target;
> > > -
> > > -	obj[BATCH].handle = gem_create(fd, 4096);
> > > -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> > > -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> > > -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> > > -	memset(&reloc, 0, sizeof(reloc));
> > > -
> > > -	i = 0;
> > > -	delta = sizeof(uint32_t) * offset_value;
> > > -	if (!ahnd) {
> > > -		reloc.target_handle = obj[SCRATCH].handle;
> > > -		reloc.presumed_offset = -1;
> > > -		reloc.offset = sizeof(uint32_t) * (i + 1);
> > > -		reloc.delta = delta;
> > > -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> > > -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> > > -	} else {
> > > -		obj[SCRATCH].offset = target_offset;
> > > -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> > > -		obj[BATCH].offset = bb_offset;
> > > -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> > > -	}
> > > -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> > > -	if (gen >= 8) {
> > > -		batch[++i] = target_offset + delta;
> > > -		batch[++i] = target_offset >> 32;
> > > -	} else if (gen >= 4) {
> > > -		batch[++i] = 0;
> > > -		batch[++i] = delta;
> > > -		reloc.offset += sizeof(uint32_t);
> > > -	} else {
> > > -		batch[i]--;
> > > -		batch[++i] = delta;
> > > -	}
> > > -	batch[++i] = offset_value;
> > > -	batch[++i] = MI_BATCH_BUFFER_END;
> > > -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> > > -	gem_execbuf(fd, &execbuf);
> > > -	gem_close(fd, obj[BATCH].handle);
> > > -	put_offset(ahnd, obj[BATCH].handle);
> > > -}
> > > -
> > >   static bool fence_busy(int fence)
> > >   {
> > >   	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
> > > @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
> > >   			continue;
> > >   		if (flags & NONBLOCK) {
> > > -			store(fd, ahnd, ctx, e2, spin->out_fence,
> > > -			      scratch, scratch_offset, i);
> > > +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> > > +				       scratch, scratch_offset, i, i);
> > >   		} else {
> > >   			igt_fork(child, 1) {
> > >   				ahnd = get_reloc_ahnd(fd, ctx->id);
> > > -				store(fd, ahnd, ctx, e2, spin->out_fence,
> > > -				      scratch, scratch_offset, i);
> > > +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> > > +					       scratch, scratch_offset, i, i);
> > >   				put_ahnd(ahnd);
> > >   			}
> > >   		}
> > > diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> > > index 6656b3fcd..5a0c9497c 100644
> > > --- a/tests/i915/i915_hangman.c
> > > +++ b/tests/i915/i915_hangman.c
> > > @@ -36,6 +36,7 @@
> > >   #include "i915/gem.h"
> > >   #include "i915/gem_create.h"
> > >   #include "igt.h"
> > > +#include "igt_store.h"
> > >   #include "igt_sysfs.h"
> > >   #include "igt_debugfs.h"
> > >   #include "sw_sync.h"
> > > -- 
> > > 2.25.1
> > > 
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
@ 2022-01-13 20:23         ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:23 UTC (permalink / raw)
  To: John Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 12:27:00PM -0800, John Harrison wrote:
> On 1/13/2022 12:10, Matthew Brost wrote:
> > On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
> > > From: John Harrison <John.C.Harrison@Intel.com>
> > > 
> > > A lot of tests use almost identical code for creating a batch buffer
> > > which does a single write to memory and another is about to be added.
> > > Instead, move the most generic version into a common helper function.
> > > Unfortunately, the other instances are all subtly different enough to
> > > make it not so trivial to try to use the helper. It could be done but
> > > it is unclear if it is worth the effort at this point. This patch
> > > proves the concept, if people like it enough then it can be extended.
> > > 
> > > v2: Fix up object address vs store offset confusion (with help from
> > > Zbigniew K).
> > > 
> > > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > > ---
> > >   lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
> > >   lib/igt_store.h             | 12 +++++
> > >   lib/meson.build             |  1 +
> > >   tests/i915/gem_exec_fence.c | 77 ++---------------------------
> > >   tests/i915/i915_hangman.c   |  1 +
> > >   5 files changed, 115 insertions(+), 72 deletions(-)
> > >   create mode 100644 lib/igt_store.c
> > >   create mode 100644 lib/igt_store.h
> > > 
> > > diff --git a/lib/igt_store.c b/lib/igt_store.c
> > > new file mode 100644
> > > index 000000000..42c888b55
> > > --- /dev/null
> > > +++ b/lib/igt_store.c
> > > @@ -0,0 +1,96 @@
> > > +/* SPDX-License-Identifier: MIT */
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#include "i915/gem_create.h"
> > > +#include "igt_core.h"
> > > +#include "drmtest.h"
> > > +#include "igt_store.h"
> > > +#include "intel_chipset.h"
> > > +#include "intel_reg.h"
> > > +#include "ioctl_wrappers.h"
> > > +#include "lib/intel_allocator.h"
> > > +
> > > +/**
> > > + * SECTION:igt_store_word
> > > + * @short_description: Library for writing a value to memory
> > > + * @title: StoreWord
> > > + * @include: igt.h
> > > + *
> > > + * A lot of igt testcases need some mechanism for writing a value to memory
> > > + * as a test that a batch buffer has executed.
> > > + *
> > > + * NB: Requires master for STORE_DWORD on gen4/5.
> > > + */
> > > +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > +		    const struct intel_execution_engine2 *e,
> > > +		    int fence, uint32_t target_handle,
> > > +		    uint64_t target_gpu_addr,
> > > +		    uint64_t store_offset, uint32_t store_value)
> > > +{
> > > +	const int SCRATCH = 0;
> > > +	const int BATCH = 1;
> > > +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> > > +	struct drm_i915_gem_exec_object2 obj[2];
> > > +	struct drm_i915_gem_relocation_entry reloc;
> > > +	struct drm_i915_gem_execbuffer2 execbuf;
> > > +	uint32_t batch[16], delta;
> > > +	uint64_t bb_offset;
> > > +	int i;
> > > +
> > > +	memset(&execbuf, 0, sizeof(execbuf));
> > > +	execbuf.buffers_ptr = to_user_pointer(obj);
> > > +	execbuf.buffer_count = ARRAY_SIZE(obj);
> > > +	execbuf.flags = e->flags;
> > > +	execbuf.rsvd1 = ctx->id;
> > > +	if (fence != -1) {
> > > +		execbuf.flags |= I915_EXEC_FENCE_IN;
> > > +		execbuf.rsvd2 = fence;
> > > +	}
> > > +	if (gen < 6)
> > > +		execbuf.flags |= I915_EXEC_SECURE;
> > > +
> > > +	memset(obj, 0, sizeof(obj));
> > > +	obj[SCRATCH].handle = target_handle;
> > > +
> > > +	obj[BATCH].handle = gem_create(fd, 4096);
> > > +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> > > +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> > > +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> > > +	memset(&reloc, 0, sizeof(reloc));
> > > +
> > > +	i = 0;
> > > +	delta = sizeof(uint32_t) * store_offset;
> > Can't this overflow the delta as store_offset is a u64?
> Oops.
> 
> Yeah, this code was a right mess of data words being used as addresses and
> random copies supporting 64bit or only 32bit offsets. I believe it's
> currently fine as even platforms which can theoretically support >32bits
> don't actually use it. But yes, will repost with a 64bit version of delta.
> 
> > 
> > > +	if (!ahnd) {
> > > +		reloc.target_handle = obj[SCRATCH].handle;
> > > +		reloc.presumed_offset = -1;
> > > +		reloc.offset = sizeof(uint32_t) * (i + 1);

Then just be safe, probably assert the upper 32 bits of delta are clear too.

Matt

> > > +		reloc.delta = delta;
> > > +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> > > +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> > > +	} else {
> > > +		obj[SCRATCH].offset = target_gpu_addr;
> > > +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> > > +		obj[BATCH].offset = bb_offset;
> > > +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> > > +	}
> > > +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> > > +	if (gen >= 8) {
> > > +		batch[++i] = target_gpu_addr + delta;
> > > +		batch[++i] = (target_gpu_addr + delta) >> 32;
> > This is different from the previous code, presumably this is fixing a
> > bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
> > 32 bits?
> > 
> > Matt
> Yeah, some copies of this code were definitely broken for >32bit addresses.
> 
> John.
> 
> > 
> > > +	} else if (gen >= 4) {
> > > +		batch[++i] = 0;
> > > +		batch[++i] = delta;
> > > +		reloc.offset += sizeof(uint32_t);
> > > +	} else {
> > > +		batch[i]--;
> > > +		batch[++i] = delta;
> > > +	}
> > > +	batch[++i] = store_value;
> > > +	batch[++i] = MI_BATCH_BUFFER_END;
> > > +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> > > +	gem_execbuf(fd, &execbuf);
> > > +	gem_close(fd, obj[BATCH].handle);
> > > +	put_offset(ahnd, obj[BATCH].handle);
> > > +}
> > > diff --git a/lib/igt_store.h b/lib/igt_store.h
> > > new file mode 100644
> > > index 000000000..5c6c8263c
> > > --- /dev/null
> > > +++ b/lib/igt_store.h
> > > @@ -0,0 +1,12 @@
> > > +/* SPDX-License-Identifier: MIT */
> > > +/*
> > > + * Copyright © 2021 Intel Corporation
> > > + */
> > > +
> > > +#include "igt_gt.h"
> > > +
> > > +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > +		    const struct intel_execution_engine2 *e,
> > > +		    int fence, uint32_t target_handle,
> > > +		    uint64_t target_gpu_addr,
> > > +		    uint64_t store_offset, uint32_t store_value);
> > > diff --git a/lib/meson.build b/lib/meson.build
> > > index b9568a71b..3e43316d1 100644
> > > --- a/lib/meson.build
> > > +++ b/lib/meson.build
> > > @@ -72,6 +72,7 @@ lib_sources = [
> > >   	'igt_map.c',
> > >   	'igt_pm.c',
> > >   	'igt_dummyload.c',
> > > +	'igt_store.c',
> > >   	'uwildmat/uwildmat.c',
> > >   	'igt_kmod.c',
> > >   	'igt_panfrost.c',
> > > diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
> > > index 9a6336ce9..196236b27 100644
> > > --- a/tests/i915/gem_exec_fence.c
> > > +++ b/tests/i915/gem_exec_fence.c
> > > @@ -28,6 +28,7 @@
> > >   #include "i915/gem.h"
> > >   #include "i915/gem_create.h"
> > >   #include "igt.h"
> > > +#include "igt_store.h"
> > >   #include "igt_syncobj.h"
> > >   #include "igt_sysfs.h"
> > >   #include "igt_vgem.h"
> > > @@ -57,74 +58,6 @@ struct sync_merge_data {
> > >   #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
> > >   #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
> > > -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> > > -		  const struct intel_execution_engine2 *e,
> > > -		  int fence, uint32_t target, uint64_t target_offset,
> > > -		  unsigned offset_value)
> > > -{
> > > -	const int SCRATCH = 0;
> > > -	const int BATCH = 1;
> > > -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> > > -	struct drm_i915_gem_exec_object2 obj[2];
> > > -	struct drm_i915_gem_relocation_entry reloc;
> > > -	struct drm_i915_gem_execbuffer2 execbuf;
> > > -	uint32_t batch[16], delta;
> > > -	uint64_t bb_offset;
> > > -	int i;
> > > -
> > > -	memset(&execbuf, 0, sizeof(execbuf));
> > > -	execbuf.buffers_ptr = to_user_pointer(obj);
> > > -	execbuf.buffer_count = 2;
> > > -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
> > > -	execbuf.rsvd1 = ctx->id;
> > > -	execbuf.rsvd2 = fence;
> > > -	if (gen < 6)
> > > -		execbuf.flags |= I915_EXEC_SECURE;
> > > -
> > > -	memset(obj, 0, sizeof(obj));
> > > -	obj[SCRATCH].handle = target;
> > > -
> > > -	obj[BATCH].handle = gem_create(fd, 4096);
> > > -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> > > -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> > > -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> > > -	memset(&reloc, 0, sizeof(reloc));
> > > -
> > > -	i = 0;
> > > -	delta = sizeof(uint32_t) * offset_value;
> > > -	if (!ahnd) {
> > > -		reloc.target_handle = obj[SCRATCH].handle;
> > > -		reloc.presumed_offset = -1;
> > > -		reloc.offset = sizeof(uint32_t) * (i + 1);
> > > -		reloc.delta = delta;
> > > -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> > > -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> > > -	} else {
> > > -		obj[SCRATCH].offset = target_offset;
> > > -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> > > -		obj[BATCH].offset = bb_offset;
> > > -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> > > -	}
> > > -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> > > -	if (gen >= 8) {
> > > -		batch[++i] = target_offset + delta;
> > > -		batch[++i] = target_offset >> 32;
> > > -	} else if (gen >= 4) {
> > > -		batch[++i] = 0;
> > > -		batch[++i] = delta;
> > > -		reloc.offset += sizeof(uint32_t);
> > > -	} else {
> > > -		batch[i]--;
> > > -		batch[++i] = delta;
> > > -	}
> > > -	batch[++i] = offset_value;
> > > -	batch[++i] = MI_BATCH_BUFFER_END;
> > > -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> > > -	gem_execbuf(fd, &execbuf);
> > > -	gem_close(fd, obj[BATCH].handle);
> > > -	put_offset(ahnd, obj[BATCH].handle);
> > > -}
> > > -
> > >   static bool fence_busy(int fence)
> > >   {
> > >   	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
> > > @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
> > >   			continue;
> > >   		if (flags & NONBLOCK) {
> > > -			store(fd, ahnd, ctx, e2, spin->out_fence,
> > > -			      scratch, scratch_offset, i);
> > > +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> > > +				       scratch, scratch_offset, i, i);
> > >   		} else {
> > >   			igt_fork(child, 1) {
> > >   				ahnd = get_reloc_ahnd(fd, ctx->id);
> > > -				store(fd, ahnd, ctx, e2, spin->out_fence,
> > > -				      scratch, scratch_offset, i);
> > > +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> > > +					       scratch, scratch_offset, i, i);
> > >   				put_ahnd(ahnd);
> > >   			}
> > >   		}
> > > diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> > > index 6656b3fcd..5a0c9497c 100644
> > > --- a/tests/i915/i915_hangman.c
> > > +++ b/tests/i915/i915_hangman.c
> > > @@ -36,6 +36,7 @@
> > >   #include "i915/gem.h"
> > >   #include "i915/gem_create.h"
> > >   #include "igt.h"
> > > +#include "igt_store.h"
> > >   #include "igt_sysfs.h"
> > >   #include "igt_debugfs.h"
> > >   #include "sw_sync.h"
> > > -- 
> > > 2.25.1
> > > 
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
  2022-01-13 20:10   ` [Intel-gfx] " Matthew Brost
@ 2022-01-13 20:27       ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 20:27 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 12:10, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> A lot of tests use almost identical code for creating a batch buffer
>> which does a single write to memory and another is about to be added.
>> Instead, move the most generic version into a common helper function.
>> Unfortunately, the other instances are all subtly different enough to
>> make it not so trivial to try to use the helper. It could be done but
>> it is unclear if it is worth the effort at this point. This patch
>> proves the concept, if people like it enough then it can be extended.
>>
>> v2: Fix up object address vs store offset confusion (with help from
>> Zbigniew K).
>>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
>>   lib/igt_store.h             | 12 +++++
>>   lib/meson.build             |  1 +
>>   tests/i915/gem_exec_fence.c | 77 ++---------------------------
>>   tests/i915/i915_hangman.c   |  1 +
>>   5 files changed, 115 insertions(+), 72 deletions(-)
>>   create mode 100644 lib/igt_store.c
>>   create mode 100644 lib/igt_store.h
>>
>> diff --git a/lib/igt_store.c b/lib/igt_store.c
>> new file mode 100644
>> index 000000000..42c888b55
>> --- /dev/null
>> +++ b/lib/igt_store.c
>> @@ -0,0 +1,96 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2021 Intel Corporation
>> + */
>> +
>> +#include "i915/gem_create.h"
>> +#include "igt_core.h"
>> +#include "drmtest.h"
>> +#include "igt_store.h"
>> +#include "intel_chipset.h"
>> +#include "intel_reg.h"
>> +#include "ioctl_wrappers.h"
>> +#include "lib/intel_allocator.h"
>> +
>> +/**
>> + * SECTION:igt_store_word
>> + * @short_description: Library for writing a value to memory
>> + * @title: StoreWord
>> + * @include: igt.h
>> + *
>> + * A lot of igt testcases need some mechanism for writing a value to memory
>> + * as a test that a batch buffer has executed.
>> + *
>> + * NB: Requires master for STORE_DWORD on gen4/5.
>> + */
>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> +		    const struct intel_execution_engine2 *e,
>> +		    int fence, uint32_t target_handle,
>> +		    uint64_t target_gpu_addr,
>> +		    uint64_t store_offset, uint32_t store_value)
>> +{
>> +	const int SCRATCH = 0;
>> +	const int BATCH = 1;
>> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>> +	struct drm_i915_gem_exec_object2 obj[2];
>> +	struct drm_i915_gem_relocation_entry reloc;
>> +	struct drm_i915_gem_execbuffer2 execbuf;
>> +	uint32_t batch[16], delta;
>> +	uint64_t bb_offset;
>> +	int i;
>> +
>> +	memset(&execbuf, 0, sizeof(execbuf));
>> +	execbuf.buffers_ptr = to_user_pointer(obj);
>> +	execbuf.buffer_count = ARRAY_SIZE(obj);
>> +	execbuf.flags = e->flags;
>> +	execbuf.rsvd1 = ctx->id;
>> +	if (fence != -1) {
>> +		execbuf.flags |= I915_EXEC_FENCE_IN;
>> +		execbuf.rsvd2 = fence;
>> +	}
>> +	if (gen < 6)
>> +		execbuf.flags |= I915_EXEC_SECURE;
>> +
>> +	memset(obj, 0, sizeof(obj));
>> +	obj[SCRATCH].handle = target_handle;
>> +
>> +	obj[BATCH].handle = gem_create(fd, 4096);
>> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>> +	memset(&reloc, 0, sizeof(reloc));
>> +
>> +	i = 0;
>> +	delta = sizeof(uint32_t) * store_offset;
> Can't this overflow the delta as store_offset is a u64?
Oops.

Yeah, this code was a right mess of data words being used as addresses 
and random copies supporting 64bit or only 32bit offsets. I believe it's 
currently fine as even platforms which can theoretically support >32bits 
don't actually use it. But yes, will repost with a 64bit version of delta.

>
>> +	if (!ahnd) {
>> +		reloc.target_handle = obj[SCRATCH].handle;
>> +		reloc.presumed_offset = -1;
>> +		reloc.offset = sizeof(uint32_t) * (i + 1);
>> +		reloc.delta = delta;
>> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>> +	} else {
>> +		obj[SCRATCH].offset = target_gpu_addr;
>> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>> +		obj[BATCH].offset = bb_offset;
>> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>> +	}
>> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>> +	if (gen >= 8) {
>> +		batch[++i] = target_gpu_addr + delta;
>> +		batch[++i] = (target_gpu_addr + delta) >> 32;
> This is different from the previous code, presumably this is fixing a
> bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
> 32 bits?
>
> Matt
Yeah, some copies of this code were definitely broken for >32bit addresses.

John.

>
>> +	} else if (gen >= 4) {
>> +		batch[++i] = 0;
>> +		batch[++i] = delta;
>> +		reloc.offset += sizeof(uint32_t);
>> +	} else {
>> +		batch[i]--;
>> +		batch[++i] = delta;
>> +	}
>> +	batch[++i] = store_value;
>> +	batch[++i] = MI_BATCH_BUFFER_END;
>> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>> +	gem_execbuf(fd, &execbuf);
>> +	gem_close(fd, obj[BATCH].handle);
>> +	put_offset(ahnd, obj[BATCH].handle);
>> +}
>> diff --git a/lib/igt_store.h b/lib/igt_store.h
>> new file mode 100644
>> index 000000000..5c6c8263c
>> --- /dev/null
>> +++ b/lib/igt_store.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2021 Intel Corporation
>> + */
>> +
>> +#include "igt_gt.h"
>> +
>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> +		    const struct intel_execution_engine2 *e,
>> +		    int fence, uint32_t target_handle,
>> +		    uint64_t target_gpu_addr,
>> +		    uint64_t store_offset, uint32_t store_value);
>> diff --git a/lib/meson.build b/lib/meson.build
>> index b9568a71b..3e43316d1 100644
>> --- a/lib/meson.build
>> +++ b/lib/meson.build
>> @@ -72,6 +72,7 @@ lib_sources = [
>>   	'igt_map.c',
>>   	'igt_pm.c',
>>   	'igt_dummyload.c',
>> +	'igt_store.c',
>>   	'uwildmat/uwildmat.c',
>>   	'igt_kmod.c',
>>   	'igt_panfrost.c',
>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>> index 9a6336ce9..196236b27 100644
>> --- a/tests/i915/gem_exec_fence.c
>> +++ b/tests/i915/gem_exec_fence.c
>> @@ -28,6 +28,7 @@
>>   #include "i915/gem.h"
>>   #include "i915/gem_create.h"
>>   #include "igt.h"
>> +#include "igt_store.h"
>>   #include "igt_syncobj.h"
>>   #include "igt_sysfs.h"
>>   #include "igt_vgem.h"
>> @@ -57,74 +58,6 @@ struct sync_merge_data {
>>   #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>>   #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>>   
>> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> -		  const struct intel_execution_engine2 *e,
>> -		  int fence, uint32_t target, uint64_t target_offset,
>> -		  unsigned offset_value)
>> -{
>> -	const int SCRATCH = 0;
>> -	const int BATCH = 1;
>> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>> -	struct drm_i915_gem_exec_object2 obj[2];
>> -	struct drm_i915_gem_relocation_entry reloc;
>> -	struct drm_i915_gem_execbuffer2 execbuf;
>> -	uint32_t batch[16], delta;
>> -	uint64_t bb_offset;
>> -	int i;
>> -
>> -	memset(&execbuf, 0, sizeof(execbuf));
>> -	execbuf.buffers_ptr = to_user_pointer(obj);
>> -	execbuf.buffer_count = 2;
>> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
>> -	execbuf.rsvd1 = ctx->id;
>> -	execbuf.rsvd2 = fence;
>> -	if (gen < 6)
>> -		execbuf.flags |= I915_EXEC_SECURE;
>> -
>> -	memset(obj, 0, sizeof(obj));
>> -	obj[SCRATCH].handle = target;
>> -
>> -	obj[BATCH].handle = gem_create(fd, 4096);
>> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>> -	memset(&reloc, 0, sizeof(reloc));
>> -
>> -	i = 0;
>> -	delta = sizeof(uint32_t) * offset_value;
>> -	if (!ahnd) {
>> -		reloc.target_handle = obj[SCRATCH].handle;
>> -		reloc.presumed_offset = -1;
>> -		reloc.offset = sizeof(uint32_t) * (i + 1);
>> -		reloc.delta = delta;
>> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>> -	} else {
>> -		obj[SCRATCH].offset = target_offset;
>> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>> -		obj[BATCH].offset = bb_offset;
>> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>> -	}
>> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>> -	if (gen >= 8) {
>> -		batch[++i] = target_offset + delta;
>> -		batch[++i] = target_offset >> 32;
>> -	} else if (gen >= 4) {
>> -		batch[++i] = 0;
>> -		batch[++i] = delta;
>> -		reloc.offset += sizeof(uint32_t);
>> -	} else {
>> -		batch[i]--;
>> -		batch[++i] = delta;
>> -	}
>> -	batch[++i] = offset_value;
>> -	batch[++i] = MI_BATCH_BUFFER_END;
>> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>> -	gem_execbuf(fd, &execbuf);
>> -	gem_close(fd, obj[BATCH].handle);
>> -	put_offset(ahnd, obj[BATCH].handle);
>> -}
>> -
>>   static bool fence_busy(int fence)
>>   {
>>   	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
>> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>>   			continue;
>>   
>>   		if (flags & NONBLOCK) {
>> -			store(fd, ahnd, ctx, e2, spin->out_fence,
>> -			      scratch, scratch_offset, i);
>> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>> +				       scratch, scratch_offset, i, i);
>>   		} else {
>>   			igt_fork(child, 1) {
>>   				ahnd = get_reloc_ahnd(fd, ctx->id);
>> -				store(fd, ahnd, ctx, e2, spin->out_fence,
>> -				      scratch, scratch_offset, i);
>> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>> +					       scratch, scratch_offset, i, i);
>>   				put_ahnd(ahnd);
>>   			}
>>   		}
>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>> index 6656b3fcd..5a0c9497c 100644
>> --- a/tests/i915/i915_hangman.c
>> +++ b/tests/i915/i915_hangman.c
>> @@ -36,6 +36,7 @@
>>   #include "i915/gem.h"
>>   #include "i915/gem_create.h"
>>   #include "igt.h"
>> +#include "igt_store.h"
>>   #include "igt_sysfs.h"
>>   #include "igt_debugfs.h"
>>   #include "sw_sync.h"
>> -- 
>> 2.25.1
>>


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

* Re: [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
@ 2022-01-13 20:27       ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 20:27 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 12:10, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> A lot of tests use almost identical code for creating a batch buffer
>> which does a single write to memory and another is about to be added.
>> Instead, move the most generic version into a common helper function.
>> Unfortunately, the other instances are all subtly different enough to
>> make it not so trivial to try to use the helper. It could be done but
>> it is unclear if it is worth the effort at this point. This patch
>> proves the concept, if people like it enough then it can be extended.
>>
>> v2: Fix up object address vs store offset confusion (with help from
>> Zbigniew K).
>>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
>>   lib/igt_store.h             | 12 +++++
>>   lib/meson.build             |  1 +
>>   tests/i915/gem_exec_fence.c | 77 ++---------------------------
>>   tests/i915/i915_hangman.c   |  1 +
>>   5 files changed, 115 insertions(+), 72 deletions(-)
>>   create mode 100644 lib/igt_store.c
>>   create mode 100644 lib/igt_store.h
>>
>> diff --git a/lib/igt_store.c b/lib/igt_store.c
>> new file mode 100644
>> index 000000000..42c888b55
>> --- /dev/null
>> +++ b/lib/igt_store.c
>> @@ -0,0 +1,96 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2021 Intel Corporation
>> + */
>> +
>> +#include "i915/gem_create.h"
>> +#include "igt_core.h"
>> +#include "drmtest.h"
>> +#include "igt_store.h"
>> +#include "intel_chipset.h"
>> +#include "intel_reg.h"
>> +#include "ioctl_wrappers.h"
>> +#include "lib/intel_allocator.h"
>> +
>> +/**
>> + * SECTION:igt_store_word
>> + * @short_description: Library for writing a value to memory
>> + * @title: StoreWord
>> + * @include: igt.h
>> + *
>> + * A lot of igt testcases need some mechanism for writing a value to memory
>> + * as a test that a batch buffer has executed.
>> + *
>> + * NB: Requires master for STORE_DWORD on gen4/5.
>> + */
>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> +		    const struct intel_execution_engine2 *e,
>> +		    int fence, uint32_t target_handle,
>> +		    uint64_t target_gpu_addr,
>> +		    uint64_t store_offset, uint32_t store_value)
>> +{
>> +	const int SCRATCH = 0;
>> +	const int BATCH = 1;
>> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>> +	struct drm_i915_gem_exec_object2 obj[2];
>> +	struct drm_i915_gem_relocation_entry reloc;
>> +	struct drm_i915_gem_execbuffer2 execbuf;
>> +	uint32_t batch[16], delta;
>> +	uint64_t bb_offset;
>> +	int i;
>> +
>> +	memset(&execbuf, 0, sizeof(execbuf));
>> +	execbuf.buffers_ptr = to_user_pointer(obj);
>> +	execbuf.buffer_count = ARRAY_SIZE(obj);
>> +	execbuf.flags = e->flags;
>> +	execbuf.rsvd1 = ctx->id;
>> +	if (fence != -1) {
>> +		execbuf.flags |= I915_EXEC_FENCE_IN;
>> +		execbuf.rsvd2 = fence;
>> +	}
>> +	if (gen < 6)
>> +		execbuf.flags |= I915_EXEC_SECURE;
>> +
>> +	memset(obj, 0, sizeof(obj));
>> +	obj[SCRATCH].handle = target_handle;
>> +
>> +	obj[BATCH].handle = gem_create(fd, 4096);
>> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>> +	memset(&reloc, 0, sizeof(reloc));
>> +
>> +	i = 0;
>> +	delta = sizeof(uint32_t) * store_offset;
> Can't this overflow the delta as store_offset is a u64?
Oops.

Yeah, this code was a right mess of data words being used as addresses 
and random copies supporting 64bit or only 32bit offsets. I believe it's 
currently fine as even platforms which can theoretically support >32bits 
don't actually use it. But yes, will repost with a 64bit version of delta.

>
>> +	if (!ahnd) {
>> +		reloc.target_handle = obj[SCRATCH].handle;
>> +		reloc.presumed_offset = -1;
>> +		reloc.offset = sizeof(uint32_t) * (i + 1);
>> +		reloc.delta = delta;
>> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>> +	} else {
>> +		obj[SCRATCH].offset = target_gpu_addr;
>> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>> +		obj[BATCH].offset = bb_offset;
>> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>> +	}
>> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>> +	if (gen >= 8) {
>> +		batch[++i] = target_gpu_addr + delta;
>> +		batch[++i] = (target_gpu_addr + delta) >> 32;
> This is different from the previous code, presumably this is fixing a
> bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
> 32 bits?
>
> Matt
Yeah, some copies of this code were definitely broken for >32bit addresses.

John.

>
>> +	} else if (gen >= 4) {
>> +		batch[++i] = 0;
>> +		batch[++i] = delta;
>> +		reloc.offset += sizeof(uint32_t);
>> +	} else {
>> +		batch[i]--;
>> +		batch[++i] = delta;
>> +	}
>> +	batch[++i] = store_value;
>> +	batch[++i] = MI_BATCH_BUFFER_END;
>> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>> +	gem_execbuf(fd, &execbuf);
>> +	gem_close(fd, obj[BATCH].handle);
>> +	put_offset(ahnd, obj[BATCH].handle);
>> +}
>> diff --git a/lib/igt_store.h b/lib/igt_store.h
>> new file mode 100644
>> index 000000000..5c6c8263c
>> --- /dev/null
>> +++ b/lib/igt_store.h
>> @@ -0,0 +1,12 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright © 2021 Intel Corporation
>> + */
>> +
>> +#include "igt_gt.h"
>> +
>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> +		    const struct intel_execution_engine2 *e,
>> +		    int fence, uint32_t target_handle,
>> +		    uint64_t target_gpu_addr,
>> +		    uint64_t store_offset, uint32_t store_value);
>> diff --git a/lib/meson.build b/lib/meson.build
>> index b9568a71b..3e43316d1 100644
>> --- a/lib/meson.build
>> +++ b/lib/meson.build
>> @@ -72,6 +72,7 @@ lib_sources = [
>>   	'igt_map.c',
>>   	'igt_pm.c',
>>   	'igt_dummyload.c',
>> +	'igt_store.c',
>>   	'uwildmat/uwildmat.c',
>>   	'igt_kmod.c',
>>   	'igt_panfrost.c',
>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>> index 9a6336ce9..196236b27 100644
>> --- a/tests/i915/gem_exec_fence.c
>> +++ b/tests/i915/gem_exec_fence.c
>> @@ -28,6 +28,7 @@
>>   #include "i915/gem.h"
>>   #include "i915/gem_create.h"
>>   #include "igt.h"
>> +#include "igt_store.h"
>>   #include "igt_syncobj.h"
>>   #include "igt_sysfs.h"
>>   #include "igt_vgem.h"
>> @@ -57,74 +58,6 @@ struct sync_merge_data {
>>   #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>>   #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>>   
>> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>> -		  const struct intel_execution_engine2 *e,
>> -		  int fence, uint32_t target, uint64_t target_offset,
>> -		  unsigned offset_value)
>> -{
>> -	const int SCRATCH = 0;
>> -	const int BATCH = 1;
>> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>> -	struct drm_i915_gem_exec_object2 obj[2];
>> -	struct drm_i915_gem_relocation_entry reloc;
>> -	struct drm_i915_gem_execbuffer2 execbuf;
>> -	uint32_t batch[16], delta;
>> -	uint64_t bb_offset;
>> -	int i;
>> -
>> -	memset(&execbuf, 0, sizeof(execbuf));
>> -	execbuf.buffers_ptr = to_user_pointer(obj);
>> -	execbuf.buffer_count = 2;
>> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
>> -	execbuf.rsvd1 = ctx->id;
>> -	execbuf.rsvd2 = fence;
>> -	if (gen < 6)
>> -		execbuf.flags |= I915_EXEC_SECURE;
>> -
>> -	memset(obj, 0, sizeof(obj));
>> -	obj[SCRATCH].handle = target;
>> -
>> -	obj[BATCH].handle = gem_create(fd, 4096);
>> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>> -	memset(&reloc, 0, sizeof(reloc));
>> -
>> -	i = 0;
>> -	delta = sizeof(uint32_t) * offset_value;
>> -	if (!ahnd) {
>> -		reloc.target_handle = obj[SCRATCH].handle;
>> -		reloc.presumed_offset = -1;
>> -		reloc.offset = sizeof(uint32_t) * (i + 1);
>> -		reloc.delta = delta;
>> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>> -	} else {
>> -		obj[SCRATCH].offset = target_offset;
>> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>> -		obj[BATCH].offset = bb_offset;
>> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>> -	}
>> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>> -	if (gen >= 8) {
>> -		batch[++i] = target_offset + delta;
>> -		batch[++i] = target_offset >> 32;
>> -	} else if (gen >= 4) {
>> -		batch[++i] = 0;
>> -		batch[++i] = delta;
>> -		reloc.offset += sizeof(uint32_t);
>> -	} else {
>> -		batch[i]--;
>> -		batch[++i] = delta;
>> -	}
>> -	batch[++i] = offset_value;
>> -	batch[++i] = MI_BATCH_BUFFER_END;
>> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>> -	gem_execbuf(fd, &execbuf);
>> -	gem_close(fd, obj[BATCH].handle);
>> -	put_offset(ahnd, obj[BATCH].handle);
>> -}
>> -
>>   static bool fence_busy(int fence)
>>   {
>>   	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
>> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>>   			continue;
>>   
>>   		if (flags & NONBLOCK) {
>> -			store(fd, ahnd, ctx, e2, spin->out_fence,
>> -			      scratch, scratch_offset, i);
>> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>> +				       scratch, scratch_offset, i, i);
>>   		} else {
>>   			igt_fork(child, 1) {
>>   				ahnd = get_reloc_ahnd(fd, ctx->id);
>> -				store(fd, ahnd, ctx, e2, spin->out_fence,
>> -				      scratch, scratch_offset, i);
>> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>> +					       scratch, scratch_offset, i, i);
>>   				put_ahnd(ahnd);
>>   			}
>>   		}
>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>> index 6656b3fcd..5a0c9497c 100644
>> --- a/tests/i915/i915_hangman.c
>> +++ b/tests/i915/i915_hangman.c
>> @@ -36,6 +36,7 @@
>>   #include "i915/gem.h"
>>   #include "i915/gem_create.h"
>>   #include "igt.h"
>> +#include "igt_store.h"
>>   #include "igt_sysfs.h"
>>   #include "igt_debugfs.h"
>>   #include "sw_sync.h"
>> -- 
>> 2.25.1
>>

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 20:30     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:30 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:41AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The hang test was relying on context persitence for no particular
> reason. That is, it would set a bunch of background spinners running
> then immediately destroy the active contexts but expect the spinners
> to keep spinning. With the current implementation of context
> persistence in i915, that means that super high priority pings are
> sent to each engine at the start of the test. Depending upon the
> timing and platform, one of those unexpected pings could cause test
> failures.
> 
> There is no need to require context persitence in this test. So change
> to managing the contexts cleanly and only destroying them when they
> are no longer in use.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/i915_hangman.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 918418760..6601db5f6 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
>  {
>  	const struct intel_execution_engine2 *other;
> -	const intel_ctx_t *tmp_ctx;
> +	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];

This is fine for now as GEM_MAX_ENGINES is relatively small but what if
we change this to large value, let's say 4k? I think the stack could
overflow then. Maybe not a concern, maybe it is? I'll leave this up to
if this should be kmalloc'd or not in the next rev.

Everything else looks good.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

>  	igt_spin_t *spin, *next;
>  	IGT_LIST_HEAD(list);
>  	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
> +	int num_ctx;
>  
>  	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
>  		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
>  
>  	/* Fill all the other engines with background load */
> +	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		if (other->flags == e->flags)
>  			continue;
>  
> -		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
> -		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
> +		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -				      .ctx = tmp_ctx,
> +				      .ctx = local_ctx[num_ctx],
>  				      .engine = other->flags,
>  				      .flags = IGT_SPIN_FENCE_OUT);
> -		intel_ctx_destroy(device, tmp_ctx);
> +		num_ctx++;
>  
>  		igt_list_move(&spin->link, &list);
>  	}
> @@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		igt_spin_free(device, spin);
>  		put_ahnd(ahndN);
>  	}
> +
>  	put_ahnd(ahnd);
> +	while (num_ctx)
> +		intel_ctx_destroy(device, local_ctx[--num_ctx]);
>  
>  	check_alive();
>  }
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
@ 2022-01-13 20:30     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:30 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:41AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The hang test was relying on context persitence for no particular
> reason. That is, it would set a bunch of background spinners running
> then immediately destroy the active contexts but expect the spinners
> to keep spinning. With the current implementation of context
> persistence in i915, that means that super high priority pings are
> sent to each engine at the start of the test. Depending upon the
> timing and platform, one of those unexpected pings could cause test
> failures.
> 
> There is no need to require context persitence in this test. So change
> to managing the contexts cleanly and only destroying them when they
> are no longer in use.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/i915_hangman.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 918418760..6601db5f6 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
>  {
>  	const struct intel_execution_engine2 *other;
> -	const intel_ctx_t *tmp_ctx;
> +	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];

This is fine for now as GEM_MAX_ENGINES is relatively small but what if
we change this to large value, let's say 4k? I think the stack could
overflow then. Maybe not a concern, maybe it is? I'll leave this up to
if this should be kmalloc'd or not in the next rev.

Everything else looks good.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

>  	igt_spin_t *spin, *next;
>  	IGT_LIST_HEAD(list);
>  	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
> +	int num_ctx;
>  
>  	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
>  		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
>  
>  	/* Fill all the other engines with background load */
> +	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		if (other->flags == e->flags)
>  			continue;
>  
> -		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
> -		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
> +		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -				      .ctx = tmp_ctx,
> +				      .ctx = local_ctx[num_ctx],
>  				      .engine = other->flags,
>  				      .flags = IGT_SPIN_FENCE_OUT);
> -		intel_ctx_destroy(device, tmp_ctx);
> +		num_ctx++;
>  
>  		igt_list_move(&spin->link, &list);
>  	}
> @@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
>  		igt_spin_free(device, spin);
>  		put_ahnd(ahndN);
>  	}
> +
>  	put_ahnd(ahnd);
> +	while (num_ctx)
> +		intel_ctx_destroy(device, local_ctx[--num_ctx]);
>  
>  	check_alive();
>  }
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
  2022-01-13 20:42     ` [Intel-gfx] " John Harrison
@ 2022-01-13 20:38         ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:38 UTC (permalink / raw)
  To: John Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 12:42:28PM -0800, John Harrison wrote:
> On 1/13/2022 12:30, Matthew Brost wrote:
> > On Thu, Jan 13, 2022 at 11:59:41AM -0800, John.C.Harrison@Intel.com wrote:
> > > From: John Harrison <John.C.Harrison@Intel.com>
> > > 
> > > The hang test was relying on context persitence for no particular
> > > reason. That is, it would set a bunch of background spinners running
> > > then immediately destroy the active contexts but expect the spinners
> > > to keep spinning. With the current implementation of context
> > > persistence in i915, that means that super high priority pings are
> > > sent to each engine at the start of the test. Depending upon the
> > > timing and platform, one of those unexpected pings could cause test
> > > failures.
> > > 
> > > There is no need to require context persitence in this test. So change
> > > to managing the contexts cleanly and only destroying them when they
> > > are no longer in use.
> > > 
> > > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > > ---
> > >   tests/i915/i915_hangman.c | 15 ++++++++++-----
> > >   1 file changed, 10 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> > > index 918418760..6601db5f6 100644
> > > --- a/tests/i915/i915_hangman.c
> > > +++ b/tests/i915/i915_hangman.c
> > > @@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
> > >   		 const struct intel_execution_engine2 *e, unsigned int flags)
> > >   {
> > >   	const struct intel_execution_engine2 *other;
> > > -	const intel_ctx_t *tmp_ctx;
> > > +	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];
> > This is fine for now as GEM_MAX_ENGINES is relatively small but what if
> > we change this to large value, let's say 4k? I think the stack could
> > overflow then. Maybe not a concern, maybe it is? I'll leave this up to
> > if this should be kmalloc'd or not in the next rev.
> Seems unlikely we are going that big any time soon. And such stack reduction
> can always be done as part of any huge engine count update. Although, this
> is userland not kernel - you can slap gigabytes on the stack and it won't
> blow up ;).
> 

Right, I realized after I sent this the stack in user land matter far
less. Should be fine.

Matt

> John.
> 
> > Everything else looks good.
> > 
> > With that:
> > Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> > 
> > >   	igt_spin_t *spin, *next;
> > >   	IGT_LIST_HEAD(list);
> > >   	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
> > > +	int num_ctx;
> > >   	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
> > >   		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
> > >   	/* Fill all the other engines with background load */
> > > +	num_ctx = 0;
> > >   	for_each_ctx_engine(device, ctx, other) {
> > >   		if (other->flags == e->flags)
> > >   			continue;
> > > -		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
> > > -		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
> > > +		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> > > +		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
> > >   		spin = __igt_spin_new(device,
> > >   				      .ahnd = ahndN,
> > > -				      .ctx = tmp_ctx,
> > > +				      .ctx = local_ctx[num_ctx],
> > >   				      .engine = other->flags,
> > >   				      .flags = IGT_SPIN_FENCE_OUT);
> > > -		intel_ctx_destroy(device, tmp_ctx);
> > > +		num_ctx++;
> > >   		igt_list_move(&spin->link, &list);
> > >   	}
> > > @@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
> > >   		igt_spin_free(device, spin);
> > >   		put_ahnd(ahndN);
> > >   	}
> > > +
> > >   	put_ahnd(ahnd);
> > > +	while (num_ctx)
> > > +		intel_ctx_destroy(device, local_ctx[--num_ctx]);
> > >   	check_alive();
> > >   }
> > > -- 
> > > 2.25.1
> > > 
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
@ 2022-01-13 20:38         ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:38 UTC (permalink / raw)
  To: John Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 12:42:28PM -0800, John Harrison wrote:
> On 1/13/2022 12:30, Matthew Brost wrote:
> > On Thu, Jan 13, 2022 at 11:59:41AM -0800, John.C.Harrison@Intel.com wrote:
> > > From: John Harrison <John.C.Harrison@Intel.com>
> > > 
> > > The hang test was relying on context persitence for no particular
> > > reason. That is, it would set a bunch of background spinners running
> > > then immediately destroy the active contexts but expect the spinners
> > > to keep spinning. With the current implementation of context
> > > persistence in i915, that means that super high priority pings are
> > > sent to each engine at the start of the test. Depending upon the
> > > timing and platform, one of those unexpected pings could cause test
> > > failures.
> > > 
> > > There is no need to require context persitence in this test. So change
> > > to managing the contexts cleanly and only destroying them when they
> > > are no longer in use.
> > > 
> > > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > > ---
> > >   tests/i915/i915_hangman.c | 15 ++++++++++-----
> > >   1 file changed, 10 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> > > index 918418760..6601db5f6 100644
> > > --- a/tests/i915/i915_hangman.c
> > > +++ b/tests/i915/i915_hangman.c
> > > @@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
> > >   		 const struct intel_execution_engine2 *e, unsigned int flags)
> > >   {
> > >   	const struct intel_execution_engine2 *other;
> > > -	const intel_ctx_t *tmp_ctx;
> > > +	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];
> > This is fine for now as GEM_MAX_ENGINES is relatively small but what if
> > we change this to large value, let's say 4k? I think the stack could
> > overflow then. Maybe not a concern, maybe it is? I'll leave this up to
> > if this should be kmalloc'd or not in the next rev.
> Seems unlikely we are going that big any time soon. And such stack reduction
> can always be done as part of any huge engine count update. Although, this
> is userland not kernel - you can slap gigabytes on the stack and it won't
> blow up ;).
> 

Right, I realized after I sent this the stack in user land matter far
less. Should be fine.

Matt

> John.
> 
> > Everything else looks good.
> > 
> > With that:
> > Reviewed-by: Matthew Brost <matthew.brost@intel.com>
> > 
> > >   	igt_spin_t *spin, *next;
> > >   	IGT_LIST_HEAD(list);
> > >   	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
> > > +	int num_ctx;
> > >   	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
> > >   		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
> > >   	/* Fill all the other engines with background load */
> > > +	num_ctx = 0;
> > >   	for_each_ctx_engine(device, ctx, other) {
> > >   		if (other->flags == e->flags)
> > >   			continue;
> > > -		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
> > > -		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
> > > +		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> > > +		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
> > >   		spin = __igt_spin_new(device,
> > >   				      .ahnd = ahndN,
> > > -				      .ctx = tmp_ctx,
> > > +				      .ctx = local_ctx[num_ctx],
> > >   				      .engine = other->flags,
> > >   				      .flags = IGT_SPIN_FENCE_OUT);
> > > -		intel_ctx_destroy(device, tmp_ctx);
> > > +		num_ctx++;
> > >   		igt_list_move(&spin->link, &list);
> > >   	}
> > > @@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
> > >   		igt_spin_free(device, spin);
> > >   		put_ahnd(ahndN);
> > >   	}
> > > +
> > >   	put_ahnd(ahnd);
> > > +	while (num_ctx)
> > > +		intel_ctx_destroy(device, local_ctx[--num_ctx]);
> > >   	check_alive();
> > >   }
> > > -- 
> > > 2.25.1
> > > 
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
  2022-01-13 20:23         ` Matthew Brost
@ 2022-01-13 20:40           ` John Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 20:40 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 12:23, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 12:27:00PM -0800, John Harrison wrote:
>> On 1/13/2022 12:10, Matthew Brost wrote:
>>> On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
>>>> From: John Harrison <John.C.Harrison@Intel.com>
>>>>
>>>> A lot of tests use almost identical code for creating a batch buffer
>>>> which does a single write to memory and another is about to be added.
>>>> Instead, move the most generic version into a common helper function.
>>>> Unfortunately, the other instances are all subtly different enough to
>>>> make it not so trivial to try to use the helper. It could be done but
>>>> it is unclear if it is worth the effort at this point. This patch
>>>> proves the concept, if people like it enough then it can be extended.
>>>>
>>>> v2: Fix up object address vs store offset confusion (with help from
>>>> Zbigniew K).
>>>>
>>>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>>>> ---
>>>>    lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
>>>>    lib/igt_store.h             | 12 +++++
>>>>    lib/meson.build             |  1 +
>>>>    tests/i915/gem_exec_fence.c | 77 ++---------------------------
>>>>    tests/i915/i915_hangman.c   |  1 +
>>>>    5 files changed, 115 insertions(+), 72 deletions(-)
>>>>    create mode 100644 lib/igt_store.c
>>>>    create mode 100644 lib/igt_store.h
>>>>
>>>> diff --git a/lib/igt_store.c b/lib/igt_store.c
>>>> new file mode 100644
>>>> index 000000000..42c888b55
>>>> --- /dev/null
>>>> +++ b/lib/igt_store.c
>>>> @@ -0,0 +1,96 @@
>>>> +/* SPDX-License-Identifier: MIT */
>>>> +/*
>>>> + * Copyright © 2021 Intel Corporation
>>>> + */
>>>> +
>>>> +#include "i915/gem_create.h"
>>>> +#include "igt_core.h"
>>>> +#include "drmtest.h"
>>>> +#include "igt_store.h"
>>>> +#include "intel_chipset.h"
>>>> +#include "intel_reg.h"
>>>> +#include "ioctl_wrappers.h"
>>>> +#include "lib/intel_allocator.h"
>>>> +
>>>> +/**
>>>> + * SECTION:igt_store_word
>>>> + * @short_description: Library for writing a value to memory
>>>> + * @title: StoreWord
>>>> + * @include: igt.h
>>>> + *
>>>> + * A lot of igt testcases need some mechanism for writing a value to memory
>>>> + * as a test that a batch buffer has executed.
>>>> + *
>>>> + * NB: Requires master for STORE_DWORD on gen4/5.
>>>> + */
>>>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> +		    const struct intel_execution_engine2 *e,
>>>> +		    int fence, uint32_t target_handle,
>>>> +		    uint64_t target_gpu_addr,
>>>> +		    uint64_t store_offset, uint32_t store_value)
>>>> +{
>>>> +	const int SCRATCH = 0;
>>>> +	const int BATCH = 1;
>>>> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>>>> +	struct drm_i915_gem_exec_object2 obj[2];
>>>> +	struct drm_i915_gem_relocation_entry reloc;
>>>> +	struct drm_i915_gem_execbuffer2 execbuf;
>>>> +	uint32_t batch[16], delta;
>>>> +	uint64_t bb_offset;
>>>> +	int i;
>>>> +
>>>> +	memset(&execbuf, 0, sizeof(execbuf));
>>>> +	execbuf.buffers_ptr = to_user_pointer(obj);
>>>> +	execbuf.buffer_count = ARRAY_SIZE(obj);
>>>> +	execbuf.flags = e->flags;
>>>> +	execbuf.rsvd1 = ctx->id;
>>>> +	if (fence != -1) {
>>>> +		execbuf.flags |= I915_EXEC_FENCE_IN;
>>>> +		execbuf.rsvd2 = fence;
>>>> +	}
>>>> +	if (gen < 6)
>>>> +		execbuf.flags |= I915_EXEC_SECURE;
>>>> +
>>>> +	memset(obj, 0, sizeof(obj));
>>>> +	obj[SCRATCH].handle = target_handle;
>>>> +
>>>> +	obj[BATCH].handle = gem_create(fd, 4096);
>>>> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>>>> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>>>> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>>>> +	memset(&reloc, 0, sizeof(reloc));
>>>> +
>>>> +	i = 0;
>>>> +	delta = sizeof(uint32_t) * store_offset;
>>> Can't this overflow the delta as store_offset is a u64?
>> Oops.
>>
>> Yeah, this code was a right mess of data words being used as addresses and
>> random copies supporting 64bit or only 32bit offsets. I believe it's
>> currently fine as even platforms which can theoretically support >32bits
>> don't actually use it. But yes, will repost with a 64bit version of delta.
>>
>>>> +	if (!ahnd) {
>>>> +		reloc.target_handle = obj[SCRATCH].handle;
>>>> +		reloc.presumed_offset = -1;
>>>> +		reloc.offset = sizeof(uint32_t) * (i + 1);
> Then just be safe, probably assert the upper 32 bits of delta are clear too.
Indeed. And in the <gen8 cases below.

John.

> Matt
>
>>>> +		reloc.delta = delta;
>>>> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>>>> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>>>> +	} else {
>>>> +		obj[SCRATCH].offset = target_gpu_addr;
>>>> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>>>> +		obj[BATCH].offset = bb_offset;
>>>> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>>>> +	}
>>>> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>>>> +	if (gen >= 8) {
>>>> +		batch[++i] = target_gpu_addr + delta;
>>>> +		batch[++i] = (target_gpu_addr + delta) >> 32;
>>> This is different from the previous code, presumably this is fixing a
>>> bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
>>> 32 bits?
>>>
>>> Matt
>> Yeah, some copies of this code were definitely broken for >32bit addresses.
>>
>> John.
>>
>>>> +	} else if (gen >= 4) {
>>>> +		batch[++i] = 0;
>>>> +		batch[++i] = delta;
>>>> +		reloc.offset += sizeof(uint32_t);
>>>> +	} else {
>>>> +		batch[i]--;
>>>> +		batch[++i] = delta;
>>>> +	}
>>>> +	batch[++i] = store_value;
>>>> +	batch[++i] = MI_BATCH_BUFFER_END;
>>>> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>>>> +	gem_execbuf(fd, &execbuf);
>>>> +	gem_close(fd, obj[BATCH].handle);
>>>> +	put_offset(ahnd, obj[BATCH].handle);
>>>> +}
>>>> diff --git a/lib/igt_store.h b/lib/igt_store.h
>>>> new file mode 100644
>>>> index 000000000..5c6c8263c
>>>> --- /dev/null
>>>> +++ b/lib/igt_store.h
>>>> @@ -0,0 +1,12 @@
>>>> +/* SPDX-License-Identifier: MIT */
>>>> +/*
>>>> + * Copyright © 2021 Intel Corporation
>>>> + */
>>>> +
>>>> +#include "igt_gt.h"
>>>> +
>>>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> +		    const struct intel_execution_engine2 *e,
>>>> +		    int fence, uint32_t target_handle,
>>>> +		    uint64_t target_gpu_addr,
>>>> +		    uint64_t store_offset, uint32_t store_value);
>>>> diff --git a/lib/meson.build b/lib/meson.build
>>>> index b9568a71b..3e43316d1 100644
>>>> --- a/lib/meson.build
>>>> +++ b/lib/meson.build
>>>> @@ -72,6 +72,7 @@ lib_sources = [
>>>>    	'igt_map.c',
>>>>    	'igt_pm.c',
>>>>    	'igt_dummyload.c',
>>>> +	'igt_store.c',
>>>>    	'uwildmat/uwildmat.c',
>>>>    	'igt_kmod.c',
>>>>    	'igt_panfrost.c',
>>>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>>>> index 9a6336ce9..196236b27 100644
>>>> --- a/tests/i915/gem_exec_fence.c
>>>> +++ b/tests/i915/gem_exec_fence.c
>>>> @@ -28,6 +28,7 @@
>>>>    #include "i915/gem.h"
>>>>    #include "i915/gem_create.h"
>>>>    #include "igt.h"
>>>> +#include "igt_store.h"
>>>>    #include "igt_syncobj.h"
>>>>    #include "igt_sysfs.h"
>>>>    #include "igt_vgem.h"
>>>> @@ -57,74 +58,6 @@ struct sync_merge_data {
>>>>    #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>>>>    #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>>>> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> -		  const struct intel_execution_engine2 *e,
>>>> -		  int fence, uint32_t target, uint64_t target_offset,
>>>> -		  unsigned offset_value)
>>>> -{
>>>> -	const int SCRATCH = 0;
>>>> -	const int BATCH = 1;
>>>> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>>>> -	struct drm_i915_gem_exec_object2 obj[2];
>>>> -	struct drm_i915_gem_relocation_entry reloc;
>>>> -	struct drm_i915_gem_execbuffer2 execbuf;
>>>> -	uint32_t batch[16], delta;
>>>> -	uint64_t bb_offset;
>>>> -	int i;
>>>> -
>>>> -	memset(&execbuf, 0, sizeof(execbuf));
>>>> -	execbuf.buffers_ptr = to_user_pointer(obj);
>>>> -	execbuf.buffer_count = 2;
>>>> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
>>>> -	execbuf.rsvd1 = ctx->id;
>>>> -	execbuf.rsvd2 = fence;
>>>> -	if (gen < 6)
>>>> -		execbuf.flags |= I915_EXEC_SECURE;
>>>> -
>>>> -	memset(obj, 0, sizeof(obj));
>>>> -	obj[SCRATCH].handle = target;
>>>> -
>>>> -	obj[BATCH].handle = gem_create(fd, 4096);
>>>> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>>>> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>>>> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>>>> -	memset(&reloc, 0, sizeof(reloc));
>>>> -
>>>> -	i = 0;
>>>> -	delta = sizeof(uint32_t) * offset_value;
>>>> -	if (!ahnd) {
>>>> -		reloc.target_handle = obj[SCRATCH].handle;
>>>> -		reloc.presumed_offset = -1;
>>>> -		reloc.offset = sizeof(uint32_t) * (i + 1);
>>>> -		reloc.delta = delta;
>>>> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>>>> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>>>> -	} else {
>>>> -		obj[SCRATCH].offset = target_offset;
>>>> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>>>> -		obj[BATCH].offset = bb_offset;
>>>> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>>>> -	}
>>>> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>>>> -	if (gen >= 8) {
>>>> -		batch[++i] = target_offset + delta;
>>>> -		batch[++i] = target_offset >> 32;
>>>> -	} else if (gen >= 4) {
>>>> -		batch[++i] = 0;
>>>> -		batch[++i] = delta;
>>>> -		reloc.offset += sizeof(uint32_t);
>>>> -	} else {
>>>> -		batch[i]--;
>>>> -		batch[++i] = delta;
>>>> -	}
>>>> -	batch[++i] = offset_value;
>>>> -	batch[++i] = MI_BATCH_BUFFER_END;
>>>> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>>>> -	gem_execbuf(fd, &execbuf);
>>>> -	gem_close(fd, obj[BATCH].handle);
>>>> -	put_offset(ahnd, obj[BATCH].handle);
>>>> -}
>>>> -
>>>>    static bool fence_busy(int fence)
>>>>    {
>>>>    	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
>>>> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>>>>    			continue;
>>>>    		if (flags & NONBLOCK) {
>>>> -			store(fd, ahnd, ctx, e2, spin->out_fence,
>>>> -			      scratch, scratch_offset, i);
>>>> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>>>> +				       scratch, scratch_offset, i, i);
>>>>    		} else {
>>>>    			igt_fork(child, 1) {
>>>>    				ahnd = get_reloc_ahnd(fd, ctx->id);
>>>> -				store(fd, ahnd, ctx, e2, spin->out_fence,
>>>> -				      scratch, scratch_offset, i);
>>>> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>>>> +					       scratch, scratch_offset, i, i);
>>>>    				put_ahnd(ahnd);
>>>>    			}
>>>>    		}
>>>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>>>> index 6656b3fcd..5a0c9497c 100644
>>>> --- a/tests/i915/i915_hangman.c
>>>> +++ b/tests/i915/i915_hangman.c
>>>> @@ -36,6 +36,7 @@
>>>>    #include "i915/gem.h"
>>>>    #include "i915/gem_create.h"
>>>>    #include "igt.h"
>>>> +#include "igt_store.h"
>>>>    #include "igt_sysfs.h"
>>>>    #include "igt_debugfs.h"
>>>>    #include "sw_sync.h"
>>>> -- 
>>>> 2.25.1
>>>>


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

* Re: [igt-dev] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function
@ 2022-01-13 20:40           ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 20:40 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 12:23, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 12:27:00PM -0800, John Harrison wrote:
>> On 1/13/2022 12:10, Matthew Brost wrote:
>>> On Thu, Jan 13, 2022 at 11:59:39AM -0800, John.C.Harrison@Intel.com wrote:
>>>> From: John Harrison <John.C.Harrison@Intel.com>
>>>>
>>>> A lot of tests use almost identical code for creating a batch buffer
>>>> which does a single write to memory and another is about to be added.
>>>> Instead, move the most generic version into a common helper function.
>>>> Unfortunately, the other instances are all subtly different enough to
>>>> make it not so trivial to try to use the helper. It could be done but
>>>> it is unclear if it is worth the effort at this point. This patch
>>>> proves the concept, if people like it enough then it can be extended.
>>>>
>>>> v2: Fix up object address vs store offset confusion (with help from
>>>> Zbigniew K).
>>>>
>>>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>>>> ---
>>>>    lib/igt_store.c             | 96 +++++++++++++++++++++++++++++++++++++
>>>>    lib/igt_store.h             | 12 +++++
>>>>    lib/meson.build             |  1 +
>>>>    tests/i915/gem_exec_fence.c | 77 ++---------------------------
>>>>    tests/i915/i915_hangman.c   |  1 +
>>>>    5 files changed, 115 insertions(+), 72 deletions(-)
>>>>    create mode 100644 lib/igt_store.c
>>>>    create mode 100644 lib/igt_store.h
>>>>
>>>> diff --git a/lib/igt_store.c b/lib/igt_store.c
>>>> new file mode 100644
>>>> index 000000000..42c888b55
>>>> --- /dev/null
>>>> +++ b/lib/igt_store.c
>>>> @@ -0,0 +1,96 @@
>>>> +/* SPDX-License-Identifier: MIT */
>>>> +/*
>>>> + * Copyright © 2021 Intel Corporation
>>>> + */
>>>> +
>>>> +#include "i915/gem_create.h"
>>>> +#include "igt_core.h"
>>>> +#include "drmtest.h"
>>>> +#include "igt_store.h"
>>>> +#include "intel_chipset.h"
>>>> +#include "intel_reg.h"
>>>> +#include "ioctl_wrappers.h"
>>>> +#include "lib/intel_allocator.h"
>>>> +
>>>> +/**
>>>> + * SECTION:igt_store_word
>>>> + * @short_description: Library for writing a value to memory
>>>> + * @title: StoreWord
>>>> + * @include: igt.h
>>>> + *
>>>> + * A lot of igt testcases need some mechanism for writing a value to memory
>>>> + * as a test that a batch buffer has executed.
>>>> + *
>>>> + * NB: Requires master for STORE_DWORD on gen4/5.
>>>> + */
>>>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> +		    const struct intel_execution_engine2 *e,
>>>> +		    int fence, uint32_t target_handle,
>>>> +		    uint64_t target_gpu_addr,
>>>> +		    uint64_t store_offset, uint32_t store_value)
>>>> +{
>>>> +	const int SCRATCH = 0;
>>>> +	const int BATCH = 1;
>>>> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>>>> +	struct drm_i915_gem_exec_object2 obj[2];
>>>> +	struct drm_i915_gem_relocation_entry reloc;
>>>> +	struct drm_i915_gem_execbuffer2 execbuf;
>>>> +	uint32_t batch[16], delta;
>>>> +	uint64_t bb_offset;
>>>> +	int i;
>>>> +
>>>> +	memset(&execbuf, 0, sizeof(execbuf));
>>>> +	execbuf.buffers_ptr = to_user_pointer(obj);
>>>> +	execbuf.buffer_count = ARRAY_SIZE(obj);
>>>> +	execbuf.flags = e->flags;
>>>> +	execbuf.rsvd1 = ctx->id;
>>>> +	if (fence != -1) {
>>>> +		execbuf.flags |= I915_EXEC_FENCE_IN;
>>>> +		execbuf.rsvd2 = fence;
>>>> +	}
>>>> +	if (gen < 6)
>>>> +		execbuf.flags |= I915_EXEC_SECURE;
>>>> +
>>>> +	memset(obj, 0, sizeof(obj));
>>>> +	obj[SCRATCH].handle = target_handle;
>>>> +
>>>> +	obj[BATCH].handle = gem_create(fd, 4096);
>>>> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>>>> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>>>> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>>>> +	memset(&reloc, 0, sizeof(reloc));
>>>> +
>>>> +	i = 0;
>>>> +	delta = sizeof(uint32_t) * store_offset;
>>> Can't this overflow the delta as store_offset is a u64?
>> Oops.
>>
>> Yeah, this code was a right mess of data words being used as addresses and
>> random copies supporting 64bit or only 32bit offsets. I believe it's
>> currently fine as even platforms which can theoretically support >32bits
>> don't actually use it. But yes, will repost with a 64bit version of delta.
>>
>>>> +	if (!ahnd) {
>>>> +		reloc.target_handle = obj[SCRATCH].handle;
>>>> +		reloc.presumed_offset = -1;
>>>> +		reloc.offset = sizeof(uint32_t) * (i + 1);
> Then just be safe, probably assert the upper 32 bits of delta are clear too.
Indeed. And in the <gen8 cases below.

John.

> Matt
>
>>>> +		reloc.delta = delta;
>>>> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>>>> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>>>> +	} else {
>>>> +		obj[SCRATCH].offset = target_gpu_addr;
>>>> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>>>> +		obj[BATCH].offset = bb_offset;
>>>> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>>>> +	}
>>>> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>>>> +	if (gen >= 8) {
>>>> +		batch[++i] = target_gpu_addr + delta;
>>>> +		batch[++i] = (target_gpu_addr + delta) >> 32;
>>> This is different from the previous code, presumably this is fixing a
>>> bug where delta + bits 31:0 of target_gpu_addr overflows into the upper
>>> 32 bits?
>>>
>>> Matt
>> Yeah, some copies of this code were definitely broken for >32bit addresses.
>>
>> John.
>>
>>>> +	} else if (gen >= 4) {
>>>> +		batch[++i] = 0;
>>>> +		batch[++i] = delta;
>>>> +		reloc.offset += sizeof(uint32_t);
>>>> +	} else {
>>>> +		batch[i]--;
>>>> +		batch[++i] = delta;
>>>> +	}
>>>> +	batch[++i] = store_value;
>>>> +	batch[++i] = MI_BATCH_BUFFER_END;
>>>> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>>>> +	gem_execbuf(fd, &execbuf);
>>>> +	gem_close(fd, obj[BATCH].handle);
>>>> +	put_offset(ahnd, obj[BATCH].handle);
>>>> +}
>>>> diff --git a/lib/igt_store.h b/lib/igt_store.h
>>>> new file mode 100644
>>>> index 000000000..5c6c8263c
>>>> --- /dev/null
>>>> +++ b/lib/igt_store.h
>>>> @@ -0,0 +1,12 @@
>>>> +/* SPDX-License-Identifier: MIT */
>>>> +/*
>>>> + * Copyright © 2021 Intel Corporation
>>>> + */
>>>> +
>>>> +#include "igt_gt.h"
>>>> +
>>>> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> +		    const struct intel_execution_engine2 *e,
>>>> +		    int fence, uint32_t target_handle,
>>>> +		    uint64_t target_gpu_addr,
>>>> +		    uint64_t store_offset, uint32_t store_value);
>>>> diff --git a/lib/meson.build b/lib/meson.build
>>>> index b9568a71b..3e43316d1 100644
>>>> --- a/lib/meson.build
>>>> +++ b/lib/meson.build
>>>> @@ -72,6 +72,7 @@ lib_sources = [
>>>>    	'igt_map.c',
>>>>    	'igt_pm.c',
>>>>    	'igt_dummyload.c',
>>>> +	'igt_store.c',
>>>>    	'uwildmat/uwildmat.c',
>>>>    	'igt_kmod.c',
>>>>    	'igt_panfrost.c',
>>>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>>>> index 9a6336ce9..196236b27 100644
>>>> --- a/tests/i915/gem_exec_fence.c
>>>> +++ b/tests/i915/gem_exec_fence.c
>>>> @@ -28,6 +28,7 @@
>>>>    #include "i915/gem.h"
>>>>    #include "i915/gem_create.h"
>>>>    #include "igt.h"
>>>> +#include "igt_store.h"
>>>>    #include "igt_syncobj.h"
>>>>    #include "igt_sysfs.h"
>>>>    #include "igt_vgem.h"
>>>> @@ -57,74 +58,6 @@ struct sync_merge_data {
>>>>    #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>>>>    #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>>>> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
>>>> -		  const struct intel_execution_engine2 *e,
>>>> -		  int fence, uint32_t target, uint64_t target_offset,
>>>> -		  unsigned offset_value)
>>>> -{
>>>> -	const int SCRATCH = 0;
>>>> -	const int BATCH = 1;
>>>> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
>>>> -	struct drm_i915_gem_exec_object2 obj[2];
>>>> -	struct drm_i915_gem_relocation_entry reloc;
>>>> -	struct drm_i915_gem_execbuffer2 execbuf;
>>>> -	uint32_t batch[16], delta;
>>>> -	uint64_t bb_offset;
>>>> -	int i;
>>>> -
>>>> -	memset(&execbuf, 0, sizeof(execbuf));
>>>> -	execbuf.buffers_ptr = to_user_pointer(obj);
>>>> -	execbuf.buffer_count = 2;
>>>> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
>>>> -	execbuf.rsvd1 = ctx->id;
>>>> -	execbuf.rsvd2 = fence;
>>>> -	if (gen < 6)
>>>> -		execbuf.flags |= I915_EXEC_SECURE;
>>>> -
>>>> -	memset(obj, 0, sizeof(obj));
>>>> -	obj[SCRATCH].handle = target;
>>>> -
>>>> -	obj[BATCH].handle = gem_create(fd, 4096);
>>>> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
>>>> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
>>>> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
>>>> -	memset(&reloc, 0, sizeof(reloc));
>>>> -
>>>> -	i = 0;
>>>> -	delta = sizeof(uint32_t) * offset_value;
>>>> -	if (!ahnd) {
>>>> -		reloc.target_handle = obj[SCRATCH].handle;
>>>> -		reloc.presumed_offset = -1;
>>>> -		reloc.offset = sizeof(uint32_t) * (i + 1);
>>>> -		reloc.delta = delta;
>>>> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
>>>> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
>>>> -	} else {
>>>> -		obj[SCRATCH].offset = target_offset;
>>>> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
>>>> -		obj[BATCH].offset = bb_offset;
>>>> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
>>>> -	}
>>>> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
>>>> -	if (gen >= 8) {
>>>> -		batch[++i] = target_offset + delta;
>>>> -		batch[++i] = target_offset >> 32;
>>>> -	} else if (gen >= 4) {
>>>> -		batch[++i] = 0;
>>>> -		batch[++i] = delta;
>>>> -		reloc.offset += sizeof(uint32_t);
>>>> -	} else {
>>>> -		batch[i]--;
>>>> -		batch[++i] = delta;
>>>> -	}
>>>> -	batch[++i] = offset_value;
>>>> -	batch[++i] = MI_BATCH_BUFFER_END;
>>>> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
>>>> -	gem_execbuf(fd, &execbuf);
>>>> -	gem_close(fd, obj[BATCH].handle);
>>>> -	put_offset(ahnd, obj[BATCH].handle);
>>>> -}
>>>> -
>>>>    static bool fence_busy(int fence)
>>>>    {
>>>>    	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
>>>> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>>>>    			continue;
>>>>    		if (flags & NONBLOCK) {
>>>> -			store(fd, ahnd, ctx, e2, spin->out_fence,
>>>> -			      scratch, scratch_offset, i);
>>>> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>>>> +				       scratch, scratch_offset, i, i);
>>>>    		} else {
>>>>    			igt_fork(child, 1) {
>>>>    				ahnd = get_reloc_ahnd(fd, ctx->id);
>>>> -				store(fd, ahnd, ctx, e2, spin->out_fence,
>>>> -				      scratch, scratch_offset, i);
>>>> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
>>>> +					       scratch, scratch_offset, i, i);
>>>>    				put_ahnd(ahnd);
>>>>    			}
>>>>    		}
>>>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>>>> index 6656b3fcd..5a0c9497c 100644
>>>> --- a/tests/i915/i915_hangman.c
>>>> +++ b/tests/i915/i915_hangman.c
>>>> @@ -36,6 +36,7 @@
>>>>    #include "i915/gem.h"
>>>>    #include "i915/gem_create.h"
>>>>    #include "igt.h"
>>>> +#include "igt_store.h"
>>>>    #include "igt_sysfs.h"
>>>>    #include "igt_debugfs.h"
>>>>    #include "sw_sync.h"
>>>> -- 
>>>> 2.25.1
>>>>

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance
  2022-01-13 20:30     ` Matthew Brost
  (?)
@ 2022-01-13 20:42     ` John Harrison
  2022-01-13 20:38         ` Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: John Harrison @ 2022-01-13 20:42 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 12:30, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:41AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The hang test was relying on context persitence for no particular
>> reason. That is, it would set a bunch of background spinners running
>> then immediately destroy the active contexts but expect the spinners
>> to keep spinning. With the current implementation of context
>> persistence in i915, that means that super high priority pings are
>> sent to each engine at the start of the test. Depending upon the
>> timing and platform, one of those unexpected pings could cause test
>> failures.
>>
>> There is no need to require context persitence in this test. So change
>> to managing the contexts cleanly and only destroying them when they
>> are no longer in use.
>>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   tests/i915/i915_hangman.c | 15 ++++++++++-----
>>   1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>> index 918418760..6601db5f6 100644
>> --- a/tests/i915/i915_hangman.c
>> +++ b/tests/i915/i915_hangman.c
>> @@ -289,27 +289,29 @@ test_engine_hang(const intel_ctx_t *ctx,
>>   		 const struct intel_execution_engine2 *e, unsigned int flags)
>>   {
>>   	const struct intel_execution_engine2 *other;
>> -	const intel_ctx_t *tmp_ctx;
>> +	const intel_ctx_t *local_ctx[GEM_MAX_ENGINES];
> This is fine for now as GEM_MAX_ENGINES is relatively small but what if
> we change this to large value, let's say 4k? I think the stack could
> overflow then. Maybe not a concern, maybe it is? I'll leave this up to
> if this should be kmalloc'd or not in the next rev.
Seems unlikely we are going that big any time soon. And such stack 
reduction can always be done as part of any huge engine count update. 
Although, this is userland not kernel - you can slap gigabytes on the 
stack and it won't blow up ;).

John.

> Everything else looks good.
>
> With that:
> Reviewed-by: Matthew Brost <matthew.brost@intel.com>
>
>>   	igt_spin_t *spin, *next;
>>   	IGT_LIST_HEAD(list);
>>   	uint64_t ahnd = get_reloc_ahnd(device, ctx->id), ahndN;
>> +	int num_ctx;
>>   
>>   	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
>>   		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
>>   
>>   	/* Fill all the other engines with background load */
>> +	num_ctx = 0;
>>   	for_each_ctx_engine(device, ctx, other) {
>>   		if (other->flags == e->flags)
>>   			continue;
>>   
>> -		tmp_ctx = intel_ctx_create(device, &ctx->cfg);
>> -		ahndN = get_reloc_ahnd(device, tmp_ctx->id);
>> +		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
>> +		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>>   		spin = __igt_spin_new(device,
>>   				      .ahnd = ahndN,
>> -				      .ctx = tmp_ctx,
>> +				      .ctx = local_ctx[num_ctx],
>>   				      .engine = other->flags,
>>   				      .flags = IGT_SPIN_FENCE_OUT);
>> -		intel_ctx_destroy(device, tmp_ctx);
>> +		num_ctx++;
>>   
>>   		igt_list_move(&spin->link, &list);
>>   	}
>> @@ -339,7 +341,10 @@ test_engine_hang(const intel_ctx_t *ctx,
>>   		igt_spin_free(device, spin);
>>   		put_ahnd(ahndN);
>>   	}
>> +
>>   	put_ahnd(ahnd);
>> +	while (num_ctx)
>> +		intel_ctx_destroy(device, local_ctx[--num_ctx]);
>>   
>>   	check_alive();
>>   }
>> -- 
>> 2.25.1
>>


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

* Re: [Intel-gfx] [PATCH v3 i-g-t 10/15] tests/i915/i915_hangman: Run background task on all engines
  2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 10/15] tests/i915/i915_hangman: Run background task on all engines John.C.Harrison
@ 2022-01-13 20:48     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:48 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:42AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> As opposed to only on the non-target engines. This means that there is
> some other workload present for the scheduler to switch between and so
> detet the hang immediately.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 6601db5f6..9f7f8062c 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -298,12 +298,14 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
>  		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
>  
> -	/* Fill all the other engines with background load */
> +	/*
> +	 * Fill all engines with background load.
> +	 * This verifies that independent engines are unaffected and gives
> +	 * the target engine something to switch between so it notices the
> +	 * hang.
> +	 */
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
> -		if (other->flags == e->flags)
> -			continue;
> -
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [Intel-gfx] [PATCH v3 i-g-t 10/15] tests/i915/i915_hangman: Run background task on all engines
@ 2022-01-13 20:48     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:48 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:42AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> As opposed to only on the non-target engines. This means that there is
> some other workload present for the scheduler to switch between and so
> detet the hang immediately.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 6601db5f6..9f7f8062c 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -298,12 +298,14 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	igt_skip_on(flags & IGT_SPIN_INVALID_CS &&
>  		    gem_engine_has_cmdparser(device, &ctx->cfg, e->flags));
>  
> -	/* Fill all the other engines with background load */
> +	/*
> +	 * Fill all engines with background load.
> +	 * This verifies that independent engines are unaffected and gives
> +	 * the target engine something to switch between so it notices the
> +	 * hang.
> +	 */
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
> -		if (other->flags == e->flags)
> -			continue;
> -
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
> -- 
> 2.25.1
> 

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

* [Intel-gfx] [PATCH i-g-t] lib/store: Refactor common store code into helper function
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 20:50     ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 20:50 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

A lot of tests use almost identical code for creating a batch buffer
which does a single write to memory and another is about to be added.
Instead, move the most generic version into a common helper function.
Unfortunately, the other instances are all subtly different enough to
make it not so trivial to try to use the helper. It could be done but
it is unclear if it is worth the effort at this point. This patch
proves the concept, if people like it enough then it can be extended.

v2: Fix up object address vs store offset confusion (with help from
Zbigniew K).
v3: Cope with >32bit store_offset (review feedback from Matthew Brost).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_store.c             | 100 ++++++++++++++++++++++++++++++++++++
 lib/igt_store.h             |  12 +++++
 lib/meson.build             |   1 +
 tests/i915/gem_exec_fence.c |  77 ++-------------------------
 tests/i915/i915_hangman.c   |   1 +
 5 files changed, 119 insertions(+), 72 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

diff --git a/lib/igt_store.c b/lib/igt_store.c
new file mode 100644
index 000000000..98c6c4fbd
--- /dev/null
+++ b/lib/igt_store.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915/gem_create.h"
+#include "igt_core.h"
+#include "drmtest.h"
+#include "igt_store.h"
+#include "intel_chipset.h"
+#include "intel_reg.h"
+#include "ioctl_wrappers.h"
+#include "lib/intel_allocator.h"
+
+/**
+ * SECTION:igt_store_word
+ * @short_description: Library for writing a value to memory
+ * @title: StoreWord
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some mechanism for writing a value to memory
+ * as a test that a batch buffer has executed.
+ *
+ * NB: Requires master for STORE_DWORD on gen4/5.
+ */
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value)
+{
+	const int SCRATCH = 0;
+	const int BATCH = 1;
+	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t batch[16];
+	uint64_t bb_offset, delta;
+	int i;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = ARRAY_SIZE(obj);
+	execbuf.flags = e->flags;
+	execbuf.rsvd1 = ctx->id;
+	if (fence != -1) {
+		execbuf.flags |= I915_EXEC_FENCE_IN;
+		execbuf.rsvd2 = fence;
+	}
+	if (gen < 6)
+		execbuf.flags |= I915_EXEC_SECURE;
+
+	memset(obj, 0, sizeof(obj));
+	obj[SCRATCH].handle = target_handle;
+
+	obj[BATCH].handle = gem_create(fd, 4096);
+	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
+	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
+	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
+	memset(&reloc, 0, sizeof(reloc));
+
+	i = 0;
+	delta = sizeof(uint32_t) * store_offset;
+	if (!ahnd) {
+		reloc.target_handle = obj[SCRATCH].handle;
+		reloc.presumed_offset = -1;
+		reloc.offset = sizeof(uint32_t) * (i + 1);
+		reloc.delta = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
+	} else {
+		obj[SCRATCH].offset = target_gpu_addr;
+		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
+		obj[BATCH].offset = bb_offset;
+		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
+	}
+	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
+	if (gen >= 8) {
+		uint64_t addr = target_gpu_addr + delta;
+		batch[++i] = lower_32_bits(addr);
+		batch[++i] = upper_32_bits(addr);
+	} else if (gen >= 4) {
+		batch[++i] = 0;
+		batch[++i] = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+		reloc.offset += sizeof(uint32_t);
+	} else {
+		batch[i]--;
+		batch[++i] = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+	}
+	batch[++i] = store_value;
+	batch[++i] = MI_BATCH_BUFFER_END;
+	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[BATCH].handle);
+	put_offset(ahnd, obj[BATCH].handle);
+}
diff --git a/lib/igt_store.h b/lib/igt_store.h
new file mode 100644
index 000000000..5c6c8263c
--- /dev/null
+++ b/lib/igt_store.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "igt_gt.h"
+
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value);
diff --git a/lib/meson.build b/lib/meson.build
index b9568a71b..3e43316d1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -72,6 +72,7 @@ lib_sources = [
 	'igt_map.c',
 	'igt_pm.c',
 	'igt_dummyload.c',
+	'igt_store.c',
 	'uwildmat/uwildmat.c',
 	'igt_kmod.c',
 	'igt_panfrost.c',
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 9a6336ce9..196236b27 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -28,6 +28,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_syncobj.h"
 #include "igt_sysfs.h"
 #include "igt_vgem.h"
@@ -57,74 +58,6 @@ struct sync_merge_data {
 #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
 #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
 
-static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
-		  const struct intel_execution_engine2 *e,
-		  int fence, uint32_t target, uint64_t target_offset,
-		  unsigned offset_value)
-{
-	const int SCRATCH = 0;
-	const int BATCH = 1;
-	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
-	struct drm_i915_gem_exec_object2 obj[2];
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	uint32_t batch[16], delta;
-	uint64_t bb_offset;
-	int i;
-
-	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(obj);
-	execbuf.buffer_count = 2;
-	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
-	execbuf.rsvd1 = ctx->id;
-	execbuf.rsvd2 = fence;
-	if (gen < 6)
-		execbuf.flags |= I915_EXEC_SECURE;
-
-	memset(obj, 0, sizeof(obj));
-	obj[SCRATCH].handle = target;
-
-	obj[BATCH].handle = gem_create(fd, 4096);
-	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
-	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
-	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
-	memset(&reloc, 0, sizeof(reloc));
-
-	i = 0;
-	delta = sizeof(uint32_t) * offset_value;
-	if (!ahnd) {
-		reloc.target_handle = obj[SCRATCH].handle;
-		reloc.presumed_offset = -1;
-		reloc.offset = sizeof(uint32_t) * (i + 1);
-		reloc.delta = delta;
-		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
-	} else {
-		obj[SCRATCH].offset = target_offset;
-		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
-		obj[BATCH].offset = bb_offset;
-		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
-	}
-	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
-	if (gen >= 8) {
-		batch[++i] = target_offset + delta;
-		batch[++i] = target_offset >> 32;
-	} else if (gen >= 4) {
-		batch[++i] = 0;
-		batch[++i] = delta;
-		reloc.offset += sizeof(uint32_t);
-	} else {
-		batch[i]--;
-		batch[++i] = delta;
-	}
-	batch[++i] = offset_value;
-	batch[++i] = MI_BATCH_BUFFER_END;
-	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
-	gem_execbuf(fd, &execbuf);
-	gem_close(fd, obj[BATCH].handle);
-	put_offset(ahnd, obj[BATCH].handle);
-}
-
 static bool fence_busy(int fence)
 {
 	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
@@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
 			continue;
 
 		if (flags & NONBLOCK) {
-			store(fd, ahnd, ctx, e2, spin->out_fence,
-			      scratch, scratch_offset, i);
+			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+				       scratch, scratch_offset, i, i);
 		} else {
 			igt_fork(child, 1) {
 				ahnd = get_reloc_ahnd(fd, ctx->id);
-				store(fd, ahnd, ctx, e2, spin->out_fence,
-				      scratch, scratch_offset, i);
+				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+					       scratch, scratch_offset, i, i);
 				put_ahnd(ahnd);
 			}
 		}
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 6656b3fcd..5a0c9497c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -36,6 +36,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_sysfs.h"
 #include "igt_debugfs.h"
 #include "sw_sync.h"
-- 
2.25.1


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

* [igt-dev] [PATCH i-g-t] lib/store: Refactor common store code into helper function
@ 2022-01-13 20:50     ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 20:50 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

A lot of tests use almost identical code for creating a batch buffer
which does a single write to memory and another is about to be added.
Instead, move the most generic version into a common helper function.
Unfortunately, the other instances are all subtly different enough to
make it not so trivial to try to use the helper. It could be done but
it is unclear if it is worth the effort at this point. This patch
proves the concept, if people like it enough then it can be extended.

v2: Fix up object address vs store offset confusion (with help from
Zbigniew K).
v3: Cope with >32bit store_offset (review feedback from Matthew Brost).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 lib/igt_store.c             | 100 ++++++++++++++++++++++++++++++++++++
 lib/igt_store.h             |  12 +++++
 lib/meson.build             |   1 +
 tests/i915/gem_exec_fence.c |  77 ++-------------------------
 tests/i915/i915_hangman.c   |   1 +
 5 files changed, 119 insertions(+), 72 deletions(-)
 create mode 100644 lib/igt_store.c
 create mode 100644 lib/igt_store.h

diff --git a/lib/igt_store.c b/lib/igt_store.c
new file mode 100644
index 000000000..98c6c4fbd
--- /dev/null
+++ b/lib/igt_store.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "i915/gem_create.h"
+#include "igt_core.h"
+#include "drmtest.h"
+#include "igt_store.h"
+#include "intel_chipset.h"
+#include "intel_reg.h"
+#include "ioctl_wrappers.h"
+#include "lib/intel_allocator.h"
+
+/**
+ * SECTION:igt_store_word
+ * @short_description: Library for writing a value to memory
+ * @title: StoreWord
+ * @include: igt.h
+ *
+ * A lot of igt testcases need some mechanism for writing a value to memory
+ * as a test that a batch buffer has executed.
+ *
+ * NB: Requires master for STORE_DWORD on gen4/5.
+ */
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value)
+{
+	const int SCRATCH = 0;
+	const int BATCH = 1;
+	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
+	struct drm_i915_gem_exec_object2 obj[2];
+	struct drm_i915_gem_relocation_entry reloc;
+	struct drm_i915_gem_execbuffer2 execbuf;
+	uint32_t batch[16];
+	uint64_t bb_offset, delta;
+	int i;
+
+	memset(&execbuf, 0, sizeof(execbuf));
+	execbuf.buffers_ptr = to_user_pointer(obj);
+	execbuf.buffer_count = ARRAY_SIZE(obj);
+	execbuf.flags = e->flags;
+	execbuf.rsvd1 = ctx->id;
+	if (fence != -1) {
+		execbuf.flags |= I915_EXEC_FENCE_IN;
+		execbuf.rsvd2 = fence;
+	}
+	if (gen < 6)
+		execbuf.flags |= I915_EXEC_SECURE;
+
+	memset(obj, 0, sizeof(obj));
+	obj[SCRATCH].handle = target_handle;
+
+	obj[BATCH].handle = gem_create(fd, 4096);
+	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
+	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
+	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
+	memset(&reloc, 0, sizeof(reloc));
+
+	i = 0;
+	delta = sizeof(uint32_t) * store_offset;
+	if (!ahnd) {
+		reloc.target_handle = obj[SCRATCH].handle;
+		reloc.presumed_offset = -1;
+		reloc.offset = sizeof(uint32_t) * (i + 1);
+		reloc.delta = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
+		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
+	} else {
+		obj[SCRATCH].offset = target_gpu_addr;
+		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
+		obj[BATCH].offset = bb_offset;
+		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
+	}
+	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
+	if (gen >= 8) {
+		uint64_t addr = target_gpu_addr + delta;
+		batch[++i] = lower_32_bits(addr);
+		batch[++i] = upper_32_bits(addr);
+	} else if (gen >= 4) {
+		batch[++i] = 0;
+		batch[++i] = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+		reloc.offset += sizeof(uint32_t);
+	} else {
+		batch[i]--;
+		batch[++i] = lower_32_bits(delta);
+		igt_assert_eq(upper_32_bits(delta), 0);
+	}
+	batch[++i] = store_value;
+	batch[++i] = MI_BATCH_BUFFER_END;
+	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
+	gem_execbuf(fd, &execbuf);
+	gem_close(fd, obj[BATCH].handle);
+	put_offset(ahnd, obj[BATCH].handle);
+}
diff --git a/lib/igt_store.h b/lib/igt_store.h
new file mode 100644
index 000000000..5c6c8263c
--- /dev/null
+++ b/lib/igt_store.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#include "igt_gt.h"
+
+void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
+		    const struct intel_execution_engine2 *e,
+		    int fence, uint32_t target_handle,
+		    uint64_t target_gpu_addr,
+		    uint64_t store_offset, uint32_t store_value);
diff --git a/lib/meson.build b/lib/meson.build
index b9568a71b..3e43316d1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -72,6 +72,7 @@ lib_sources = [
 	'igt_map.c',
 	'igt_pm.c',
 	'igt_dummyload.c',
+	'igt_store.c',
 	'uwildmat/uwildmat.c',
 	'igt_kmod.c',
 	'igt_panfrost.c',
diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
index 9a6336ce9..196236b27 100644
--- a/tests/i915/gem_exec_fence.c
+++ b/tests/i915/gem_exec_fence.c
@@ -28,6 +28,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_syncobj.h"
 #include "igt_sysfs.h"
 #include "igt_vgem.h"
@@ -57,74 +58,6 @@ struct sync_merge_data {
 #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
 #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
 
-static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
-		  const struct intel_execution_engine2 *e,
-		  int fence, uint32_t target, uint64_t target_offset,
-		  unsigned offset_value)
-{
-	const int SCRATCH = 0;
-	const int BATCH = 1;
-	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
-	struct drm_i915_gem_exec_object2 obj[2];
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	uint32_t batch[16], delta;
-	uint64_t bb_offset;
-	int i;
-
-	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(obj);
-	execbuf.buffer_count = 2;
-	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
-	execbuf.rsvd1 = ctx->id;
-	execbuf.rsvd2 = fence;
-	if (gen < 6)
-		execbuf.flags |= I915_EXEC_SECURE;
-
-	memset(obj, 0, sizeof(obj));
-	obj[SCRATCH].handle = target;
-
-	obj[BATCH].handle = gem_create(fd, 4096);
-	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
-	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
-	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
-	memset(&reloc, 0, sizeof(reloc));
-
-	i = 0;
-	delta = sizeof(uint32_t) * offset_value;
-	if (!ahnd) {
-		reloc.target_handle = obj[SCRATCH].handle;
-		reloc.presumed_offset = -1;
-		reloc.offset = sizeof(uint32_t) * (i + 1);
-		reloc.delta = delta;
-		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
-		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
-	} else {
-		obj[SCRATCH].offset = target_offset;
-		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
-		obj[BATCH].offset = bb_offset;
-		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
-	}
-	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
-	if (gen >= 8) {
-		batch[++i] = target_offset + delta;
-		batch[++i] = target_offset >> 32;
-	} else if (gen >= 4) {
-		batch[++i] = 0;
-		batch[++i] = delta;
-		reloc.offset += sizeof(uint32_t);
-	} else {
-		batch[i]--;
-		batch[++i] = delta;
-	}
-	batch[++i] = offset_value;
-	batch[++i] = MI_BATCH_BUFFER_END;
-	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
-	gem_execbuf(fd, &execbuf);
-	gem_close(fd, obj[BATCH].handle);
-	put_offset(ahnd, obj[BATCH].handle);
-}
-
 static bool fence_busy(int fence)
 {
 	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
@@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
 			continue;
 
 		if (flags & NONBLOCK) {
-			store(fd, ahnd, ctx, e2, spin->out_fence,
-			      scratch, scratch_offset, i);
+			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+				       scratch, scratch_offset, i, i);
 		} else {
 			igt_fork(child, 1) {
 				ahnd = get_reloc_ahnd(fd, ctx->id);
-				store(fd, ahnd, ctx, e2, spin->out_fence,
-				      scratch, scratch_offset, i);
+				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
+					       scratch, scratch_offset, i, i);
 				put_ahnd(ahnd);
 			}
 		}
diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 6656b3fcd..5a0c9497c 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -36,6 +36,7 @@
 #include "i915/gem.h"
 #include "i915/gem_create.h"
 #include "igt.h"
+#include "igt_store.h"
 #include "igt_sysfs.h"
 #include "igt_debugfs.h"
 #include "sw_sync.h"
-- 
2.25.1

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

* Re: [Intel-gfx] [igt-dev] [PATCH i-g-t] lib/store: Refactor common store code into helper function
  2022-01-13 20:50     ` [igt-dev] " John.C.Harrison
  (?)
@ 2022-01-13 20:53     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 20:53 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 12:50:29PM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> A lot of tests use almost identical code for creating a batch buffer
> which does a single write to memory and another is about to be added.
> Instead, move the most generic version into a common helper function.
> Unfortunately, the other instances are all subtly different enough to
> make it not so trivial to try to use the helper. It could be done but
> it is unclear if it is worth the effort at this point. This patch
> proves the concept, if people like it enough then it can be extended.
> 
> v2: Fix up object address vs store offset confusion (with help from
> Zbigniew K).
> v3: Cope with >32bit store_offset (review feedback from Matthew Brost).
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  lib/igt_store.c             | 100 ++++++++++++++++++++++++++++++++++++
>  lib/igt_store.h             |  12 +++++
>  lib/meson.build             |   1 +
>  tests/i915/gem_exec_fence.c |  77 ++-------------------------
>  tests/i915/i915_hangman.c   |   1 +
>  5 files changed, 119 insertions(+), 72 deletions(-)
>  create mode 100644 lib/igt_store.c
>  create mode 100644 lib/igt_store.h
> 
> diff --git a/lib/igt_store.c b/lib/igt_store.c
> new file mode 100644
> index 000000000..98c6c4fbd
> --- /dev/null
> +++ b/lib/igt_store.c
> @@ -0,0 +1,100 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include "i915/gem_create.h"
> +#include "igt_core.h"
> +#include "drmtest.h"
> +#include "igt_store.h"
> +#include "intel_chipset.h"
> +#include "intel_reg.h"
> +#include "ioctl_wrappers.h"
> +#include "lib/intel_allocator.h"
> +
> +/**
> + * SECTION:igt_store_word
> + * @short_description: Library for writing a value to memory
> + * @title: StoreWord
> + * @include: igt.h
> + *
> + * A lot of igt testcases need some mechanism for writing a value to memory
> + * as a test that a batch buffer has executed.
> + *
> + * NB: Requires master for STORE_DWORD on gen4/5.
> + */
> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> +		    const struct intel_execution_engine2 *e,
> +		    int fence, uint32_t target_handle,
> +		    uint64_t target_gpu_addr,
> +		    uint64_t store_offset, uint32_t store_value)
> +{
> +	const int SCRATCH = 0;
> +	const int BATCH = 1;
> +	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> +	struct drm_i915_gem_exec_object2 obj[2];
> +	struct drm_i915_gem_relocation_entry reloc;
> +	struct drm_i915_gem_execbuffer2 execbuf;
> +	uint32_t batch[16];
> +	uint64_t bb_offset, delta;
> +	int i;
> +
> +	memset(&execbuf, 0, sizeof(execbuf));
> +	execbuf.buffers_ptr = to_user_pointer(obj);
> +	execbuf.buffer_count = ARRAY_SIZE(obj);
> +	execbuf.flags = e->flags;
> +	execbuf.rsvd1 = ctx->id;
> +	if (fence != -1) {
> +		execbuf.flags |= I915_EXEC_FENCE_IN;
> +		execbuf.rsvd2 = fence;
> +	}
> +	if (gen < 6)
> +		execbuf.flags |= I915_EXEC_SECURE;
> +
> +	memset(obj, 0, sizeof(obj));
> +	obj[SCRATCH].handle = target_handle;
> +
> +	obj[BATCH].handle = gem_create(fd, 4096);
> +	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> +	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> +	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> +	memset(&reloc, 0, sizeof(reloc));
> +
> +	i = 0;
> +	delta = sizeof(uint32_t) * store_offset;
> +	if (!ahnd) {
> +		reloc.target_handle = obj[SCRATCH].handle;
> +		reloc.presumed_offset = -1;
> +		reloc.offset = sizeof(uint32_t) * (i + 1);
> +		reloc.delta = lower_32_bits(delta);
> +		igt_assert_eq(upper_32_bits(delta), 0);
> +		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> +		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> +	} else {
> +		obj[SCRATCH].offset = target_gpu_addr;
> +		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> +		obj[BATCH].offset = bb_offset;
> +		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> +	}
> +	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> +	if (gen >= 8) {
> +		uint64_t addr = target_gpu_addr + delta;
> +		batch[++i] = lower_32_bits(addr);
> +		batch[++i] = upper_32_bits(addr);
> +	} else if (gen >= 4) {
> +		batch[++i] = 0;
> +		batch[++i] = lower_32_bits(delta);
> +		igt_assert_eq(upper_32_bits(delta), 0);
> +		reloc.offset += sizeof(uint32_t);
> +	} else {
> +		batch[i]--;
> +		batch[++i] = lower_32_bits(delta);
> +		igt_assert_eq(upper_32_bits(delta), 0);
> +	}
> +	batch[++i] = store_value;
> +	batch[++i] = MI_BATCH_BUFFER_END;
> +	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> +	gem_execbuf(fd, &execbuf);
> +	gem_close(fd, obj[BATCH].handle);
> +	put_offset(ahnd, obj[BATCH].handle);
> +}
> diff --git a/lib/igt_store.h b/lib/igt_store.h
> new file mode 100644
> index 000000000..5c6c8263c
> --- /dev/null
> +++ b/lib/igt_store.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#include "igt_gt.h"
> +
> +void igt_store_word(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> +		    const struct intel_execution_engine2 *e,
> +		    int fence, uint32_t target_handle,
> +		    uint64_t target_gpu_addr,
> +		    uint64_t store_offset, uint32_t store_value);
> diff --git a/lib/meson.build b/lib/meson.build
> index b9568a71b..3e43316d1 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -72,6 +72,7 @@ lib_sources = [
>  	'igt_map.c',
>  	'igt_pm.c',
>  	'igt_dummyload.c',
> +	'igt_store.c',
>  	'uwildmat/uwildmat.c',
>  	'igt_kmod.c',
>  	'igt_panfrost.c',
> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
> index 9a6336ce9..196236b27 100644
> --- a/tests/i915/gem_exec_fence.c
> +++ b/tests/i915/gem_exec_fence.c
> @@ -28,6 +28,7 @@
>  #include "i915/gem.h"
>  #include "i915/gem_create.h"
>  #include "igt.h"
> +#include "igt_store.h"
>  #include "igt_syncobj.h"
>  #include "igt_sysfs.h"
>  #include "igt_vgem.h"
> @@ -57,74 +58,6 @@ struct sync_merge_data {
>  #define   MI_SEMAPHORE_SAD_EQ_SDD       (4 << 12)
>  #define   MI_SEMAPHORE_SAD_NEQ_SDD      (5 << 12)
>  
> -static void store(int fd, uint64_t ahnd, const intel_ctx_t *ctx,
> -		  const struct intel_execution_engine2 *e,
> -		  int fence, uint32_t target, uint64_t target_offset,
> -		  unsigned offset_value)
> -{
> -	const int SCRATCH = 0;
> -	const int BATCH = 1;
> -	const unsigned int gen = intel_gen(intel_get_drm_devid(fd));
> -	struct drm_i915_gem_exec_object2 obj[2];
> -	struct drm_i915_gem_relocation_entry reloc;
> -	struct drm_i915_gem_execbuffer2 execbuf;
> -	uint32_t batch[16], delta;
> -	uint64_t bb_offset;
> -	int i;
> -
> -	memset(&execbuf, 0, sizeof(execbuf));
> -	execbuf.buffers_ptr = to_user_pointer(obj);
> -	execbuf.buffer_count = 2;
> -	execbuf.flags = e->flags | I915_EXEC_FENCE_IN;
> -	execbuf.rsvd1 = ctx->id;
> -	execbuf.rsvd2 = fence;
> -	if (gen < 6)
> -		execbuf.flags |= I915_EXEC_SECURE;
> -
> -	memset(obj, 0, sizeof(obj));
> -	obj[SCRATCH].handle = target;
> -
> -	obj[BATCH].handle = gem_create(fd, 4096);
> -	obj[BATCH].relocs_ptr = to_user_pointer(&reloc);
> -	obj[BATCH].relocation_count = !ahnd ? 1 : 0;
> -	bb_offset = get_offset(ahnd, obj[BATCH].handle, 4096, 0);
> -	memset(&reloc, 0, sizeof(reloc));
> -
> -	i = 0;
> -	delta = sizeof(uint32_t) * offset_value;
> -	if (!ahnd) {
> -		reloc.target_handle = obj[SCRATCH].handle;
> -		reloc.presumed_offset = -1;
> -		reloc.offset = sizeof(uint32_t) * (i + 1);
> -		reloc.delta = delta;
> -		reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
> -		reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
> -	} else {
> -		obj[SCRATCH].offset = target_offset;
> -		obj[SCRATCH].flags |= EXEC_OBJECT_PINNED | EXEC_OBJECT_WRITE;
> -		obj[BATCH].offset = bb_offset;
> -		obj[BATCH].flags |= EXEC_OBJECT_PINNED;
> -	}
> -	batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
> -	if (gen >= 8) {
> -		batch[++i] = target_offset + delta;
> -		batch[++i] = target_offset >> 32;
> -	} else if (gen >= 4) {
> -		batch[++i] = 0;
> -		batch[++i] = delta;
> -		reloc.offset += sizeof(uint32_t);
> -	} else {
> -		batch[i]--;
> -		batch[++i] = delta;
> -	}
> -	batch[++i] = offset_value;
> -	batch[++i] = MI_BATCH_BUFFER_END;
> -	gem_write(fd, obj[BATCH].handle, 0, batch, sizeof(batch));
> -	gem_execbuf(fd, &execbuf);
> -	gem_close(fd, obj[BATCH].handle);
> -	put_offset(ahnd, obj[BATCH].handle);
> -}
> -
>  static bool fence_busy(int fence)
>  {
>  	return poll(&(struct pollfd){fence, POLLIN}, 1, 0) == 0;
> @@ -400,13 +333,13 @@ static void test_fence_await(int fd, const intel_ctx_t *ctx,
>  			continue;
>  
>  		if (flags & NONBLOCK) {
> -			store(fd, ahnd, ctx, e2, spin->out_fence,
> -			      scratch, scratch_offset, i);
> +			igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> +				       scratch, scratch_offset, i, i);
>  		} else {
>  			igt_fork(child, 1) {
>  				ahnd = get_reloc_ahnd(fd, ctx->id);
> -				store(fd, ahnd, ctx, e2, spin->out_fence,
> -				      scratch, scratch_offset, i);
> +				igt_store_word(fd, ahnd, ctx, e2, spin->out_fence,
> +					       scratch, scratch_offset, i, i);
>  				put_ahnd(ahnd);
>  			}
>  		}
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 6656b3fcd..5a0c9497c 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -36,6 +36,7 @@
>  #include "i915/gem.h"
>  #include "i915/gem_create.h"
>  #include "igt.h"
> +#include "igt_store.h"
>  #include "igt_sysfs.h"
>  #include "igt_debugfs.h"
>  #include "sw_sync.h"
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 21:01     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 21:01 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:43AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The global context used by all the subtests for causing hangs is
> marked as unbannable. However, some of the subtests set background
> spinners running on all engines using a freshly created context. If
> there is a test failure for any reason, all of those spinners can be
> killed off as hanging contexts. On systems with lots of engines, that
> can result in the test being banned from creating any new contexts.
> 
> So make the spinner contexts unbannable as well. That way if one
> subtest fails it won't necessarily bring down all subsequent subtests.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/i915_hangman.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 9f7f8062c..567eb71ee 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_alive();
>  }
>  
> +static void context_unban(int fd, unsigned ctx)
> +{
> +	struct drm_i915_gem_context_param param = {
> +		.ctx_id = ctx,
> +		.param = I915_CONTEXT_PARAM_BANNABLE,

Looking at the kernel I don't see how I915_CONTEXT_PARAM_BANNABLE can
return -EINVAL unless it is protected context.

> +		.value = 0,
> +	};
> +
> +	if(__gem_context_set_param(fd, &param) == -EINVAL) {
> +		igt_assert_eq(param.value, 0);
> +		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;

Also this always returns -EINVAL.

Probably can just go with:

gem_context_set_param on original parameters.

Matt

> +		gem_context_set_param(fd, &param);
> +	}
> +}
> +
>  static void
>  test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
> @@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		context_unban(device, local_ctx[num_ctx]->id);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
@ 2022-01-13 21:01     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 21:01 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:43AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The global context used by all the subtests for causing hangs is
> marked as unbannable. However, some of the subtests set background
> spinners running on all engines using a freshly created context. If
> there is a test failure for any reason, all of those spinners can be
> killed off as hanging contexts. On systems with lots of engines, that
> can result in the test being banned from creating any new contexts.
> 
> So make the spinner contexts unbannable as well. That way if one
> subtest fails it won't necessarily bring down all subsequent subtests.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/i915_hangman.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 9f7f8062c..567eb71ee 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_alive();
>  }
>  
> +static void context_unban(int fd, unsigned ctx)
> +{
> +	struct drm_i915_gem_context_param param = {
> +		.ctx_id = ctx,
> +		.param = I915_CONTEXT_PARAM_BANNABLE,

Looking at the kernel I don't see how I915_CONTEXT_PARAM_BANNABLE can
return -EINVAL unless it is protected context.

> +		.value = 0,
> +	};
> +
> +	if(__gem_context_set_param(fd, &param) == -EINVAL) {
> +		igt_assert_eq(param.value, 0);
> +		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;

Also this always returns -EINVAL.

Probably can just go with:

gem_context_set_param on original parameters.

Matt

> +		gem_context_set_param(fd, &param);
> +	}
> +}
> +
>  static void
>  test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
> @@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		context_unban(device, local_ctx[num_ctx]->id);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
  (?)
@ 2022-01-13 21:06   ` Matthew Brost
  2022-01-13 21:23       ` John Harrison
  -1 siblings, 1 reply; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 21:06 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:44AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The update to use intel_ctx_t missed a line that configures the
> context to allow hanging. Fix that.
> 
> Fixes: 09c36188b23f83ef9a7b5414e2a10100adc4291f

Typically I thought the Fixes comment was the sha from "git log
--oneline" + first line of commit message from that surrounded by ("").

So:
Fixes: <small sha> ("<message>")

With that fixed:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/gem_exec_fence.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
> index 196236b27..5e45d0518 100644
> --- a/tests/i915/gem_exec_fence.c
> +++ b/tests/i915/gem_exec_fence.c
> @@ -3139,7 +3139,7 @@ igt_main
>  			igt_hang_t hang;
>  
>  			igt_fixture {
> -				hang = igt_allow_hang(i915, 0, 0);
> +				hang = igt_allow_hang(i915, ctx->id, 0);
>  				intel_allocator_multiprocess_start();
>  			}
>  
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
  2022-01-13 21:01     ` Matthew Brost
@ 2022-01-13 21:19       ` John Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 21:19 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 13:01, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:43AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The global context used by all the subtests for causing hangs is
>> marked as unbannable. However, some of the subtests set background
>> spinners running on all engines using a freshly created context. If
>> there is a test failure for any reason, all of those spinners can be
>> killed off as hanging contexts. On systems with lots of engines, that
>> can result in the test being banned from creating any new contexts.
>>
>> So make the spinner contexts unbannable as well. That way if one
>> subtest fails it won't necessarily bring down all subsequent subtests.
>>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   tests/i915/i915_hangman.c | 16 ++++++++++++++++
>>   1 file changed, 16 insertions(+)
>>
>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>> index 9f7f8062c..567eb71ee 100644
>> --- a/tests/i915/i915_hangman.c
>> +++ b/tests/i915/i915_hangman.c
>> @@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>>   	check_alive();
>>   }
>>   
>> +static void context_unban(int fd, unsigned ctx)
>> +{
>> +	struct drm_i915_gem_context_param param = {
>> +		.ctx_id = ctx,
>> +		.param = I915_CONTEXT_PARAM_BANNABLE,
> Looking at the kernel I don't see how I915_CONTEXT_PARAM_BANNABLE can
> return -EINVAL unless it is protected context.
>
>> +		.value = 0,
>> +	};
>> +
>> +	if(__gem_context_set_param(fd, &param) == -EINVAL) {
>> +		igt_assert_eq(param.value, 0);
>> +		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
> Also this always returns -EINVAL.
>
> Probably can just go with:
>
> gem_context_set_param on original parameters.
>
> Matt
The code was just copied from 'context_set_ban' in igt_gt.c. Can't 
recall offhand why I didn't just call that function instead. There was 
some reason why it seemed better to clone it than to export the helper.

Just did a quick check of other tests that disable banning (sysfs_*, 
gem_exec_balancer, gem_exec_isolation) and they all just do a simple 
set_param(BANNABLE) and leave it at that. So I guess I'll just update 
this one to match as well.

John.


>
>> +		gem_context_set_param(fd, &param);
>> +	}
>> +}
>> +
>>   static void
>>   test_engine_hang(const intel_ctx_t *ctx,
>>   		 const struct intel_execution_engine2 *e, unsigned int flags)
>> @@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>>   	num_ctx = 0;
>>   	for_each_ctx_engine(device, ctx, other) {
>>   		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
>> +		context_unban(device, local_ctx[num_ctx]->id);
>>   		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>>   		spin = __igt_spin_new(device,
>>   				      .ahnd = ahndN,
>> -- 
>> 2.25.1
>>


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

* Re: [igt-dev] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban
@ 2022-01-13 21:19       ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 21:19 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 13:01, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:43AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The global context used by all the subtests for causing hangs is
>> marked as unbannable. However, some of the subtests set background
>> spinners running on all engines using a freshly created context. If
>> there is a test failure for any reason, all of those spinners can be
>> killed off as hanging contexts. On systems with lots of engines, that
>> can result in the test being banned from creating any new contexts.
>>
>> So make the spinner contexts unbannable as well. That way if one
>> subtest fails it won't necessarily bring down all subsequent subtests.
>>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   tests/i915/i915_hangman.c | 16 ++++++++++++++++
>>   1 file changed, 16 insertions(+)
>>
>> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
>> index 9f7f8062c..567eb71ee 100644
>> --- a/tests/i915/i915_hangman.c
>> +++ b/tests/i915/i915_hangman.c
>> @@ -284,6 +284,21 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>>   	check_alive();
>>   }
>>   
>> +static void context_unban(int fd, unsigned ctx)
>> +{
>> +	struct drm_i915_gem_context_param param = {
>> +		.ctx_id = ctx,
>> +		.param = I915_CONTEXT_PARAM_BANNABLE,
> Looking at the kernel I don't see how I915_CONTEXT_PARAM_BANNABLE can
> return -EINVAL unless it is protected context.
>
>> +		.value = 0,
>> +	};
>> +
>> +	if(__gem_context_set_param(fd, &param) == -EINVAL) {
>> +		igt_assert_eq(param.value, 0);
>> +		param.param = I915_CONTEXT_PARAM_BAN_PERIOD;
> Also this always returns -EINVAL.
>
> Probably can just go with:
>
> gem_context_set_param on original parameters.
>
> Matt
The code was just copied from 'context_set_ban' in igt_gt.c. Can't 
recall offhand why I didn't just call that function instead. There was 
some reason why it seemed better to clone it than to export the helper.

Just did a quick check of other tests that disable banning (sysfs_*, 
gem_exec_balancer, gem_exec_isolation) and they all just do a simple 
set_param(BANNABLE) and leave it at that. So I guess I'll just update 
this one to match as well.

John.


>
>> +		gem_context_set_param(fd, &param);
>> +	}
>> +}
>> +
>>   static void
>>   test_engine_hang(const intel_ctx_t *ctx,
>>   		 const struct intel_execution_engine2 *e, unsigned int flags)
>> @@ -307,6 +322,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>>   	num_ctx = 0;
>>   	for_each_ctx_engine(device, ctx, other) {
>>   		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
>> +		context_unban(device, local_ctx[num_ctx]->id);
>>   		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>>   		spin = __igt_spin_new(device,
>>   				      .ahnd = ahndN,
>> -- 
>> 2.25.1
>>

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context
  2022-01-13 21:06   ` [Intel-gfx] " Matthew Brost
@ 2022-01-13 21:23       ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 21:23 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 13:06, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:44AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The update to use intel_ctx_t missed a line that configures the
>> context to allow hanging. Fix that.
>>
>> Fixes: 09c36188b23f83ef9a7b5414e2a10100adc4291f
> Typically I thought the Fixes comment was the sha from "git log
> --oneline" + first line of commit message from that surrounded by ("").
>
> So:
> Fixes: <small sha> ("<message>")
Oops, yeah. Not sure what happened here. Brain fart most likely ;).

John.

>
> With that fixed:
> Reviewed-by: Matthew Brost <matthew.brost@intel.com>
>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   tests/i915/gem_exec_fence.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>> index 196236b27..5e45d0518 100644
>> --- a/tests/i915/gem_exec_fence.c
>> +++ b/tests/i915/gem_exec_fence.c
>> @@ -3139,7 +3139,7 @@ igt_main
>>   			igt_hang_t hang;
>>   
>>   			igt_fixture {
>> -				hang = igt_allow_hang(i915, 0, 0);
>> +				hang = igt_allow_hang(i915, ctx->id, 0);
>>   				intel_allocator_multiprocess_start();
>>   			}
>>   
>> -- 
>> 2.25.1
>>


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

* Re: [igt-dev] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context
@ 2022-01-13 21:23       ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 21:23 UTC (permalink / raw)
  To: Matthew Brost; +Cc: IGT-Dev, Intel-GFX

On 1/13/2022 13:06, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 11:59:44AM -0800, John.C.Harrison@Intel.com wrote:
>> From: John Harrison <John.C.Harrison@Intel.com>
>>
>> The update to use intel_ctx_t missed a line that configures the
>> context to allow hanging. Fix that.
>>
>> Fixes: 09c36188b23f83ef9a7b5414e2a10100adc4291f
> Typically I thought the Fixes comment was the sha from "git log
> --oneline" + first line of commit message from that surrounded by ("").
>
> So:
> Fixes: <small sha> ("<message>")
Oops, yeah. Not sure what happened here. Brain fart most likely ;).

John.

>
> With that fixed:
> Reviewed-by: Matthew Brost <matthew.brost@intel.com>
>
>> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
>> ---
>>   tests/i915/gem_exec_fence.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tests/i915/gem_exec_fence.c b/tests/i915/gem_exec_fence.c
>> index 196236b27..5e45d0518 100644
>> --- a/tests/i915/gem_exec_fence.c
>> +++ b/tests/i915/gem_exec_fence.c
>> @@ -3139,7 +3139,7 @@ igt_main
>>   			igt_hang_t hang;
>>   
>>   			igt_fixture {
>> -				hang = igt_allow_hang(i915, 0, 0);
>> +				hang = igt_allow_hang(i915, ctx->id, 0);
>>   				intel_allocator_multiprocess_start();
>>   			}
>>   
>> -- 
>> 2.25.1
>>

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

* [Intel-gfx] [PATCH i-g-t] tests/i915/i915_hangman: Don't let background contexts cause a ban
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
  (?)
  (?)
@ 2022-01-13 21:26   ` John.C.Harrison
  2022-01-13 22:30       ` [igt-dev] " Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 21:26 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

The global context used by all the subtests for causing hangs is
marked as unbannable. However, some of the subtests set background
spinners running on all engines using a freshly created context. If
there is a test failure for any reason, all of those spinners can be
killed off as hanging contexts. On systems with lots of engines, that
can result in the test being banned from creating any new contexts.

So make the spinner contexts unbannable as well. That way if one
subtest fails it won't necessarily bring down all subsequent subtests.

v2: Simplify anti-banning code (review feedback from Matthew Brost).

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 tests/i915/i915_hangman.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 9f7f8062c..537ed35a5 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -284,6 +284,17 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_alive();
 }
 
+static void context_unban(int fd, unsigned ctx)
+{
+	struct drm_i915_gem_context_param param = {
+		.ctx_id = ctx,
+		.param = I915_CONTEXT_PARAM_BANNABLE,
+		.value = 0,
+	};
+
+	gem_context_set_param(fd, &param);
+}
+
 static void
 test_engine_hang(const intel_ctx_t *ctx,
 		 const struct intel_execution_engine2 *e, unsigned int flags)
@@ -307,6 +318,7 @@ test_engine_hang(const intel_ctx_t *ctx,
 	num_ctx = 0;
 	for_each_ctx_engine(device, ctx, other) {
 		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
+		context_unban(device, local_ctx[num_ctx]->id);
 		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
 		spin = __igt_spin_new(device,
 				      .ahnd = ahndN,
-- 
2.25.1


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

* [igt-dev] ✗ Fi.CI.BAT: failure for Fixes for i915_hangman and gem_exec_capture (rev6)
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (15 preceding siblings ...)
  (?)
@ 2022-01-13 22:23 ` Patchwork
  2022-01-13 22:53   ` Matthew Brost
  -1 siblings, 1 reply; 71+ messages in thread
From: Patchwork @ 2022-01-13 22:23 UTC (permalink / raw)
  To: john.c.harrison; +Cc: igt-dev

[-- Attachment #1: Type: text/plain, Size: 8361 bytes --]

== Series Details ==

Series: Fixes for i915_hangman and gem_exec_capture (rev6)
URL   : https://patchwork.freedesktop.org/series/97981/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_11080 -> IGTPW_6553
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_6553 absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_6553, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html

Participating hosts (41 -> 41)
------------------------------

  Additional (1): fi-kbl-soraka 
  Missing    (1): fi-bsw-cyan 

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_6553:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_hangman@error-state-basic:
    - bat-dg1-6:          [PASS][1] -> [SKIP][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/bat-dg1-6/igt@i915_hangman@error-state-basic.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/bat-dg1-6/igt@i915_hangman@error-state-basic.html

  
Known issues
------------

  Here are the changes found in IGTPW_6553 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_cs_nop@sync-fork-compute0:
    - fi-snb-2600:        NOTRUN -> [SKIP][3] ([fdo#109271]) +17 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-snb-2600/igt@amdgpu/amd_cs_nop@sync-fork-compute0.html

  * igt@gem_exec_fence@basic-busy@bcs0:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][4] ([fdo#109271]) +8 similar issues
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@gem_exec_fence@basic-busy@bcs0.html

  * igt@gem_huc_copy@huc-copy:
    - fi-skl-6600u:       NOTRUN -> [SKIP][5] ([fdo#109271] / [i915#2190])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@gem_huc_copy@huc-copy.html
    - fi-kbl-soraka:      NOTRUN -> [SKIP][6] ([fdo#109271] / [i915#2190])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@basic:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][7] ([fdo#109271] / [i915#4613]) +3 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@gem_lmem_swapping@basic.html

  * igt@gem_lmem_swapping@verify-random:
    - fi-skl-6600u:       NOTRUN -> [SKIP][8] ([fdo#109271] / [i915#4613]) +3 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@gem_lmem_swapping@verify-random.html

  * igt@i915_pm_rps@basic-api:
    - bat-dg1-6:          [PASS][9] -> [FAIL][10] ([i915#4032])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/bat-dg1-6/igt@i915_pm_rps@basic-api.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/bat-dg1-6/igt@i915_pm_rps@basic-api.html

  * igt@i915_selftest@live:
    - fi-skl-6600u:       NOTRUN -> [INCOMPLETE][11] ([i915#4794])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@i915_selftest@live.html

  * igt@i915_selftest@live@gt_pm:
    - fi-kbl-soraka:      NOTRUN -> [DMESG-FAIL][12] ([i915#1886] / [i915#2291])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@i915_selftest@live@gt_pm.html

  * igt@i915_selftest@live@requests:
    - fi-blb-e6850:       [PASS][13] -> [DMESG-FAIL][14] ([i915#4528])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/fi-blb-e6850/igt@i915_selftest@live@requests.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-blb-e6850/igt@i915_selftest@live@requests.html

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-kbl-soraka:      NOTRUN -> [SKIP][15] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_chamelium@vga-edid-read:
    - fi-skl-6600u:       NOTRUN -> [SKIP][16] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@kms_chamelium@vga-edid-read.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-skl-6600u:       NOTRUN -> [SKIP][17] ([fdo#109271]) +3 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-skl-6600u:       NOTRUN -> [SKIP][18] ([fdo#109271] / [i915#533])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html
    - fi-kbl-soraka:      NOTRUN -> [SKIP][19] ([fdo#109271] / [i915#533])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-kbl-soraka/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@runner@aborted:
    - fi-blb-e6850:       NOTRUN -> [FAIL][20] ([fdo#109271] / [i915#2403] / [i915#4312])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-blb-e6850/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3@smem:
    - fi-skl-6600u:       [INCOMPLETE][21] ([i915#4547]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-skl-6600u/igt@gem_exec_suspend@basic-s3@smem.html

  * igt@i915_selftest@live@execlists:
    - {bat-jsl-1}:        [DMESG-FAIL][23] -> [PASS][24]
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/bat-jsl-1/igt@i915_selftest@live@execlists.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/bat-jsl-1/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@hangcheck:
    - fi-snb-2600:        [INCOMPLETE][25] ([i915#3921]) -> [PASS][26]
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11080/fi-snb-2600/igt@i915_selftest@live@hangcheck.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/fi-snb-2600/igt@i915_selftest@live@hangcheck.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1886]: https://gitlab.freedesktop.org/drm/intel/issues/1886
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2291]: https://gitlab.freedesktop.org/drm/intel/issues/2291
  [i915#2403]: https://gitlab.freedesktop.org/drm/intel/issues/2403
  [i915#3921]: https://gitlab.freedesktop.org/drm/intel/issues/3921
  [i915#4032]: https://gitlab.freedesktop.org/drm/intel/issues/4032
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4528]: https://gitlab.freedesktop.org/drm/intel/issues/4528
  [i915#4547]: https://gitlab.freedesktop.org/drm/intel/issues/4547
  [i915#4613]: https://gitlab.freedesktop.org/drm/intel/issues/4613
  [i915#4794]: https://gitlab.freedesktop.org/drm/intel/issues/4794
  [i915#533]: https://gitlab.freedesktop.org/drm/intel/issues/533


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_6326 -> IGTPW_6553

  CI-20190529: 20190529
  CI_DRM_11080: 8f2355c95e279e57a962843e5d7ba38885b3cfb7 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_6553: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
  IGT_6326: ec75f64fcbcf4aac58fbf1bf629e8f59b19db4ce @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git



== Testlist changes ==

+igt@i915_hangman@detector
+igt@i915_hangman@engine-engine-error
+igt@i915_hangman@engine-engine-hang
+igt@i915_hangman@engine-error-state-capture
+igt@i915_hangman@gt-engine-error
+igt@i915_hangman@gt-engine-hang
+igt@i915_hangman@gt-error-state-capture
-igt@i915_hangman@engine-error
-igt@i915_hangman@engine-hang
-igt@i915_hangman@error-state-capture

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html

[-- Attachment #2: Type: text/html, Size: 10520 bytes --]

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

* Re: [Intel-gfx] [PATCH i-g-t] tests/i915/i915_hangman: Don't let background contexts cause a ban
  2022-01-13 21:26   ` [Intel-gfx] [PATCH i-g-t] " John.C.Harrison
@ 2022-01-13 22:30       ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:30 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 01:26:53PM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The global context used by all the subtests for causing hangs is
> marked as unbannable. However, some of the subtests set background
> spinners running on all engines using a freshly created context. If
> there is a test failure for any reason, all of those spinners can be
> killed off as hanging contexts. On systems with lots of engines, that
> can result in the test being banned from creating any new contexts.
> 
> So make the spinner contexts unbannable as well. That way if one
> subtest fails it won't necessarily bring down all subsequent subtests.
> 
> v2: Simplify anti-banning code (review feedback from Matthew Brost).
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 9f7f8062c..537ed35a5 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -284,6 +284,17 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_alive();
>  }
>  
> +static void context_unban(int fd, unsigned ctx)
> +{
> +	struct drm_i915_gem_context_param param = {
> +		.ctx_id = ctx,
> +		.param = I915_CONTEXT_PARAM_BANNABLE,
> +		.value = 0,
> +	};
> +
> +	gem_context_set_param(fd, &param);
> +}
> +
>  static void
>  test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
> @@ -307,6 +318,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		context_unban(device, local_ctx[num_ctx]->id);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [Intel-gfx] [PATCH i-g-t] tests/i915/i915_hangman: Don't let background contexts cause a ban
@ 2022-01-13 22:30       ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:30 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 01:26:53PM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The global context used by all the subtests for causing hangs is
> marked as unbannable. However, some of the subtests set background
> spinners running on all engines using a freshly created context. If
> there is a test failure for any reason, all of those spinners can be
> killed off as hanging contexts. On systems with lots of engines, that
> can result in the test being banned from creating any new contexts.
> 
> So make the spinner contexts unbannable as well. That way if one
> subtest fails it won't necessarily bring down all subsequent subtests.
> 
> v2: Simplify anti-banning code (review feedback from Matthew Brost).
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/i915_hangman.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 9f7f8062c..537ed35a5 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -284,6 +284,17 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
>  	check_alive();
>  }
>  
> +static void context_unban(int fd, unsigned ctx)
> +{
> +	struct drm_i915_gem_context_param param = {
> +		.ctx_id = ctx,
> +		.param = I915_CONTEXT_PARAM_BANNABLE,
> +		.value = 0,
> +	};
> +
> +	gem_context_set_param(fd, &param);
> +}
> +
>  static void
>  test_engine_hang(const intel_ctx_t *ctx,
>  		 const struct intel_execution_engine2 *e, unsigned int flags)
> @@ -307,6 +318,7 @@ test_engine_hang(const intel_ctx_t *ctx,
>  	num_ctx = 0;
>  	for_each_ctx_engine(device, ctx, other) {
>  		local_ctx[num_ctx] = intel_ctx_create(device, &ctx->cfg);
> +		context_unban(device, local_ctx[num_ctx]->id);
>  		ahndN = get_reloc_ahnd(device, local_ctx[num_ctx]->id);
>  		spin = __igt_spin_new(device,
>  				      .ahnd = ahndN,
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 13/15] lib/i915: Add helper for non-destructive engine property updates
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 22:33     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:33 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:45AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Various tests want to configure engine properties such as pre-emption
> timeout and heartbeat interval. Some don't bother to restore the
> original values again afterwards. So, add a helper to make it easier
> to do this.
> 
> v2: Fix for platforms with no pre-emption capability.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  lib/i915/gem_engine_topology.c | 46 ++++++++++++++++++++++++++++++++++
>  lib/i915/gem_engine_topology.h |  9 +++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
> index 729f42b0a..bd12d0bc9 100644
> --- a/lib/i915/gem_engine_topology.c
> +++ b/lib/i915/gem_engine_topology.c
> @@ -488,6 +488,52 @@ int gem_engine_property_printf(int i915, const char *engine, const char *attr,
>  	return ret;
>  }
>  
> +/* Ensure fast hang detection */
> +void gem_engine_properties_configure(int fd, struct gem_engine_properties *params)
> +{
> +	int ret;
> +	struct gem_engine_properties write = *params;
> +
> +	ret = gem_engine_property_scanf(fd, write.engine->name,
> +					"heartbeat_interval_ms",
> +					"%d", &params->heartbeat_interval);
> +	igt_assert_eq(ret, 1);
> +
> +	ret = gem_engine_property_printf(fd, write.engine->name,
> +					 "heartbeat_interval_ms", "%d",
> +					 write.heartbeat_interval);
> +	igt_assert_lt(0, ret);
> +
> +	if (gem_scheduler_has_preemption(fd)) {
> +		ret = gem_engine_property_scanf(fd, write.engine->name,
> +						"preempt_timeout_ms",
> +						"%d", &params->preempt_timeout);
> +		igt_assert_eq(ret, 1);
> +
> +		ret = gem_engine_property_printf(fd, write.engine->name,
> +						 "preempt_timeout_ms", "%d",
> +						 write.preempt_timeout);
> +		igt_assert_lt(0, ret);
> +	}
> +}
> +
> +void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved)
> +{
> +	int ret;
> +
> +	ret = gem_engine_property_printf(fd, saved->engine->name,
> +					 "heartbeat_interval_ms", "%d",
> +					 saved->heartbeat_interval);
> +	igt_assert_lt(0, ret);
> +
> +	if (gem_scheduler_has_preemption(fd)) {
> +		ret = gem_engine_property_printf(fd, saved->engine->name,
> +						 "preempt_timeout_ms", "%d",
> +						 saved->preempt_timeout);
> +		igt_assert_lt(0, ret);
> +	}
> +}
> +
>  uint32_t gem_engine_mmio_base(int i915, const char *engine)
>  {
>  	unsigned int mmio = 0;
> diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
> index 4cfab560b..b413aa8ab 100644
> --- a/lib/i915/gem_engine_topology.h
> +++ b/lib/i915/gem_engine_topology.h
> @@ -115,6 +115,15 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags);
>  	     ((e__) = intel_get_current_physical_engine(&i__##e__)); \
>  	     intel_next_engine(&i__##e__))
>  
> +struct gem_engine_properties {
> +	const struct intel_execution_engine2 *engine;
> +	int preempt_timeout;
> +	int heartbeat_interval;
> +};
> +
> +void gem_engine_properties_configure(int fd, struct gem_engine_properties *params);
> +void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved);
> +
>  __attribute__((format(scanf, 4, 5)))
>  int gem_engine_property_scanf(int i915, const char *engine, const char *attr,
>  			      const char *fmt, ...);
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 13/15] lib/i915: Add helper for non-destructive engine property updates
@ 2022-01-13 22:33     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:33 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:45AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Various tests want to configure engine properties such as pre-emption
> timeout and heartbeat interval. Some don't bother to restore the
> original values again afterwards. So, add a helper to make it easier
> to do this.
> 
> v2: Fix for platforms with no pre-emption capability.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  lib/i915/gem_engine_topology.c | 46 ++++++++++++++++++++++++++++++++++
>  lib/i915/gem_engine_topology.h |  9 +++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/lib/i915/gem_engine_topology.c b/lib/i915/gem_engine_topology.c
> index 729f42b0a..bd12d0bc9 100644
> --- a/lib/i915/gem_engine_topology.c
> +++ b/lib/i915/gem_engine_topology.c
> @@ -488,6 +488,52 @@ int gem_engine_property_printf(int i915, const char *engine, const char *attr,
>  	return ret;
>  }
>  
> +/* Ensure fast hang detection */
> +void gem_engine_properties_configure(int fd, struct gem_engine_properties *params)
> +{
> +	int ret;
> +	struct gem_engine_properties write = *params;
> +
> +	ret = gem_engine_property_scanf(fd, write.engine->name,
> +					"heartbeat_interval_ms",
> +					"%d", &params->heartbeat_interval);
> +	igt_assert_eq(ret, 1);
> +
> +	ret = gem_engine_property_printf(fd, write.engine->name,
> +					 "heartbeat_interval_ms", "%d",
> +					 write.heartbeat_interval);
> +	igt_assert_lt(0, ret);
> +
> +	if (gem_scheduler_has_preemption(fd)) {
> +		ret = gem_engine_property_scanf(fd, write.engine->name,
> +						"preempt_timeout_ms",
> +						"%d", &params->preempt_timeout);
> +		igt_assert_eq(ret, 1);
> +
> +		ret = gem_engine_property_printf(fd, write.engine->name,
> +						 "preempt_timeout_ms", "%d",
> +						 write.preempt_timeout);
> +		igt_assert_lt(0, ret);
> +	}
> +}
> +
> +void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved)
> +{
> +	int ret;
> +
> +	ret = gem_engine_property_printf(fd, saved->engine->name,
> +					 "heartbeat_interval_ms", "%d",
> +					 saved->heartbeat_interval);
> +	igt_assert_lt(0, ret);
> +
> +	if (gem_scheduler_has_preemption(fd)) {
> +		ret = gem_engine_property_printf(fd, saved->engine->name,
> +						 "preempt_timeout_ms", "%d",
> +						 saved->preempt_timeout);
> +		igt_assert_lt(0, ret);
> +	}
> +}
> +
>  uint32_t gem_engine_mmio_base(int i915, const char *engine)
>  {
>  	unsigned int mmio = 0;
> diff --git a/lib/i915/gem_engine_topology.h b/lib/i915/gem_engine_topology.h
> index 4cfab560b..b413aa8ab 100644
> --- a/lib/i915/gem_engine_topology.h
> +++ b/lib/i915/gem_engine_topology.h
> @@ -115,6 +115,15 @@ struct intel_execution_engine2 gem_eb_flags_to_engine(unsigned int flags);
>  	     ((e__) = intel_get_current_physical_engine(&i__##e__)); \
>  	     intel_next_engine(&i__##e__))
>  
> +struct gem_engine_properties {
> +	const struct intel_execution_engine2 *engine;
> +	int preempt_timeout;
> +	int heartbeat_interval;
> +};
> +
> +void gem_engine_properties_configure(int fd, struct gem_engine_properties *params);
> +void gem_engine_properties_restore(int fd, const struct gem_engine_properties *saved);
> +
>  __attribute__((format(scanf, 4, 5)))
>  int gem_engine_property_scanf(int i915, const char *engine, const char *attr,
>  			      const char *fmt, ...);
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [PATCH v3 i-g-t 14/15] tests/i915/i915_hangman: Configure engine properties for quicker hangs
  2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 14/15] tests/i915/i915_hangman: Configure engine properties for quicker hangs John.C.Harrison
@ 2022-01-13 22:38   ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:38 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:46AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Some platforms have very long timeouts configured for some engines.
> Some have them disabled completely. That makes for a very slow (or
> broken) hangman test. So explicitly configure the engines to have
> reasonable settings first.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> ---
>  tests/i915/i915_hangman.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
> index 567eb71ee..1a2b2cf7a 100644
> --- a/tests/i915/i915_hangman.c
> +++ b/tests/i915/i915_hangman.c
> @@ -500,8 +500,12 @@ igt_main
>  {
>  	const intel_ctx_t *ctx;
>  	igt_hang_t hang = {};
> +	struct gem_engine_properties saved_params[GEM_MAX_ENGINES];
> +	int num_engines = 0;
>  
>  	igt_fixture {
> +		const struct intel_execution_engine2 *e;
> +
>  		device = drm_open_driver(DRIVER_INTEL);
>  		igt_require_gem(device);
>  
> @@ -515,6 +519,13 @@ igt_main
>  		igt_require(has_error_state(sysfs));
>  
>  		gem_require_mmap_wc(device);
> +
> +		for_each_physical_engine(device, e) {
> +			saved_params[num_engines].engine = e;
> +			saved_params[num_engines].preempt_timeout = 500;
> +			saved_params[num_engines].heartbeat_interval = 1000;
> +			gem_engine_properties_configure(device, saved_params + num_engines++);
> +		}
>  	}
>  
>  	igt_describe("Basic error capture");
> @@ -546,6 +557,11 @@ igt_main
>  	do_tests("engine", "engine", ctx);
>  
>  	igt_fixture {
> +		int i;
> +
> +		for (i = 0; i < num_engines; i++)
> +			gem_engine_properties_restore(device, saved_params + i);

If you wanted to be clever:

while (num_engines--)
	gem_engine_properties_restore(device, saved_params + num_engines);

Regardless:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> +
>  		igt_disallow_hang(device, hang);
>  		intel_ctx_destroy(device, ctx);
>  		close(device);
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] ✗ Fi.CI.BAT: failure for Fixes for i915_hangman and gem_exec_capture (rev6)
  2022-01-13 22:23 ` [igt-dev] ✗ Fi.CI.BAT: failure for Fixes for i915_hangman and gem_exec_capture (rev6) Patchwork
@ 2022-01-13 22:53   ` Matthew Brost
  2022-01-13 23:15     ` John Harrison
  0 siblings, 1 reply; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 22:53 UTC (permalink / raw)
  To: igt-dev

On Thu, Jan 13, 2022 at 10:23:29PM +0000, Patchwork wrote:
> Patch Details
> 
> Series:  Fixes for i915_hangman and gem_exec_capture (rev6)
> URL:     https://patchwork.freedesktop.org/series/97981/
> State:   failure
> Details: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
> 
> CI Bug Log - changes from CI_DRM_11080 -> IGTPW_6553
> 
> Summary
> 
> FAILURE
> 
> Serious unknown changes coming with IGTPW_6553 absolutely need to be
> verified manually.
> 
> If you think the reported changes have nothing to do with the changes
> introduced in IGTPW_6553, please notify your bug team to allow them
> to document this new failure mode, which will reduce false positives in CI.
> 
> External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
> 
> Participating hosts (41 -> 41)
> 
> Additional (1): fi-kbl-soraka
> Missing (1): fi-bsw-cyan
> 
> Possible new issues
> 
> Here are the unknown changes that may have been introduced in IGTPW_6553:
> 
> IGT changes
> 
> Possible regressions
> 
>   • igt@i915_hangman@error-state-basic:
>       □ bat-dg1-6: PASS -> SKIP

It looks like it is skipped because of the requirement:
Test requirement not met in function __igt_unique____real_main495, file ../tests/i915/i915_hangman.c:517:
Test requirement: gem_mmap__has_wc(device)

Which was added in this patch:
https://patchwork.freedesktop.org/patch/469465/?series=97981&rev=6

 static void do_tests(const char *name, const char *prefix,
@@ -433,6 +490,8 @@  igt_main
 		igt_assert(sysfs != -1);
 
 		igt_require(has_error_state(sysfs));
+
+		gem_require_mmap_wc(device);
 	}
 
 	igt_describe("Basic error capture");

Do discrete device not support mmap_wc?

Matt

> 
> Known issues
> 
> Here are the changes found in IGTPW_6553 that come from known issues:
> 
> IGT changes
> 
> Issues hit
> 
>   • igt@amdgpu/amd_cs_nop@sync-fork-compute0:
> 
>       □ fi-snb-2600: NOTRUN -> SKIP (fdo#109271) +17 similar issues
>   • igt@gem_exec_fence@basic-busy@bcs0:
> 
>       □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271) +8 similar issues
>   • igt@gem_huc_copy@huc-copy:
> 
>       □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#2190)
> 
>       □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#2190)
> 
>   • igt@gem_lmem_swapping@basic:
> 
>       □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#4613) +3 similar
>         issues
>   • igt@gem_lmem_swapping@verify-random:
> 
>       □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#4613) +3 similar issues
>   • igt@i915_pm_rps@basic-api:
> 
>       □ bat-dg1-6: PASS -> FAIL (i915#4032)
>   • igt@i915_selftest@live:
> 
>       □ fi-skl-6600u: NOTRUN -> INCOMPLETE (i915#4794)
>   • igt@i915_selftest@live@gt_pm:
> 
>       □ fi-kbl-soraka: NOTRUN -> DMESG-FAIL (i915#1886 / i915#2291)
>   • igt@i915_selftest@live@requests:
> 
>       □ fi-blb-e6850: PASS -> DMESG-FAIL (i915#4528)
>   • igt@kms_chamelium@common-hpd-after-suspend:
> 
>       □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / fdo#111827) +8 similar
>         issues
>   • igt@kms_chamelium@vga-edid-read:
> 
>       □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / fdo#111827) +8 similar
>         issues
>   • igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
> 
>       □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271) +3 similar issues
>   • igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
> 
>       □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#533)
> 
>       □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#533)
> 
>   • igt@runner@aborted:
> 
>       □ fi-blb-e6850: NOTRUN -> FAIL (fdo#109271 / i915#2403 / i915#4312)
> 
> Possible fixes
> 
>   • igt@gem_exec_suspend@basic-s3@smem:
> 
>       □ fi-skl-6600u: INCOMPLETE (i915#4547) -> PASS
>   • igt@i915_selftest@live@execlists:
> 
>       □ {bat-jsl-1}: DMESG-FAIL -> PASS
>   • igt@i915_selftest@live@hangcheck:
> 
>       □ fi-snb-2600: INCOMPLETE (i915#3921) -> PASS
> 
> {name}: This element is suppressed. This means it is ignored when computing
> the status of the difference (SUCCESS, WARNING, or FAILURE).
> 
> Build changes
> 
>   • CI: CI-20190529 -> None
>   • IGT: IGT_6326 -> IGTPW_6553
> 
> CI-20190529: 20190529
> CI_DRM_11080: 8f2355c95e279e57a962843e5d7ba38885b3cfb7 @ git://
> anongit.freedesktop.org/gfx-ci/linux
> IGTPW_6553: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
> IGT_6326: ec75f64fcbcf4aac58fbf1bf629e8f59b19db4ce @ https://
> gitlab.freedesktop.org/drm/igt-gpu-tools.git
> 
> == Testlist changes ==
> 
> +igt@i915_hangman@detector
> +igt@i915_hangman@engine-engine-error
> +igt@i915_hangman@engine-engine-hang
> +igt@i915_hangman@engine-error-state-capture
> +igt@i915_hangman@gt-engine-error
> +igt@i915_hangman@gt-engine-hang
> +igt@i915_hangman@gt-error-state-capture
> -igt@i915_hangman@engine-error
> -igt@i915_hangman@engine-hang
> -igt@i915_hangman@error-state-capture
> 
> SECURITY NOTE: file ~/.netrc must not be accessible by others

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

* Re: [Intel-gfx] [igt-dev] [PATCH v3 i-g-t 15/15] tests/i915/gem_exec_capture: Restore engines
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 23:04     ` Matthew Brost
  -1 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 23:04 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:47AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The test was updated some engine properties but not restoring them
> afterwards. That would leave the system in a non-default state which
> could potentially affect subsequent tests. Fix it by using the new
> save/restore engine properties helper functions.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/gem_exec_capture.c | 37 ++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c
> index 9beb36fc7..51db07c41 100644
> --- a/tests/i915/gem_exec_capture.c
> +++ b/tests/i915/gem_exec_capture.c
> @@ -209,14 +209,21 @@ static int check_error_state(int dir, struct offset *obj_offsets, int obj_count,
>  	return blobs;
>  }
>  
> -static void configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
> +static struct gem_engine_properties
> +configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
>  {
> +	struct gem_engine_properties props;
> +
>  	/* Ensure fast hang detection */
> -	gem_engine_property_printf(fd, e->name, "preempt_timeout_ms", "%d", 250);
> -	gem_engine_property_printf(fd, e->name, "heartbeat_interval_ms", "%d", 500);
> +	props.engine = e;
> +	props.preempt_timeout = 250;
> +	props.heartbeat_interval = 500;
> +	gem_engine_properties_configure(fd, &props);
>  
>  	/* Allow engine based resets and disable banning */
>  	igt_allow_hang(fd, ctxt_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
> +
> +	return props;
>  }
>  
>  static bool fence_busy(int fence)
> @@ -256,8 +263,9 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	uint32_t *batch, *seqno;
>  	struct offset offset;
>  	int i, fence_out;
> +	struct gem_engine_properties saved_engine;
>  
> -	configure_hangs(fd, e, ctx->id);
> +	saved_engine = configure_hangs(fd, e, ctx->id);
>  
>  	memset(obj, 0, sizeof(obj));
>  	obj[SCRATCH].handle = gem_create_in_memory_regions(fd, 4096, region);
> @@ -371,6 +379,8 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	gem_close(fd, obj[BATCH].handle);
>  	gem_close(fd, obj[NOCAPTURE].handle);
>  	gem_close(fd, obj[SCRATCH].handle);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static void capture(int fd, int dir, const intel_ctx_t *ctx,
> @@ -417,8 +427,9 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	uint32_t *batch, *seqno;
>  	struct offset *offsets;
>  	int i, fence_out;
> +	struct gem_engine_properties saved_engine;
>  
> -	configure_hangs(fd, e, ctx->id);
> +	saved_engine = configure_hangs(fd, e, ctx->id);
>  
>  	offsets = calloc(count, sizeof(*offsets));
>  	igt_assert(offsets);
> @@ -559,10 +570,12 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  
>  	qsort(offsets, count, sizeof(*offsets), cmp);
>  	igt_assert(offsets[0].addr <= offsets[count-1].addr);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  	return offsets;
>  }
>  
> -#define find_first_available_engine(fd, ctx, e) \
> +#define find_first_available_engine(fd, ctx, e, saved) \
>  	do { \
>  		ctx = intel_ctx_create_all_physical(fd); \
>  		igt_assert(ctx); \
> @@ -570,7 +583,7 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  			for_each_if(gem_class_can_store_dword(fd, e->class)) \
>  				break; \
>  		igt_assert(e); \
> -		configure_hangs(fd, e, ctx->id); \
> +		saved = configure_hangs(fd, e, ctx->id); \
>  	} while(0)
>  
>  static void many(int fd, int dir, uint64_t size, unsigned int flags)
> @@ -580,8 +593,9 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
>  	uint64_t ram, gtt, ahnd;
>  	unsigned long count, blobs;
>  	struct offset *offsets;
> +	struct gem_engine_properties saved_engine;
>  
> -	find_first_available_engine(fd, ctx, e);
> +	find_first_available_engine(fd, ctx, e, saved_engine);
>  
>  	gtt = gem_aperture_size(fd) / size;
>  	ram = (intel_get_avail_ram_mb() << 20) / size;
> @@ -602,6 +616,8 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
>  
>  	free(offsets);
>  	put_ahnd(ahnd);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static void prioinv(int fd, int dir, const intel_ctx_t *ctx,
> @@ -697,8 +713,9 @@ static void userptr(int fd, int dir)
>  	void *ptr;
>  	int obj_size = 4096;
>  	uint32_t system_region = INTEL_MEMORY_REGION_ID(I915_SYSTEM_MEMORY, 0);
> +	struct gem_engine_properties saved_engine;
>  
> -	find_first_available_engine(fd, ctx, e);
> +	find_first_available_engine(fd, ctx, e, saved_engine);
>  
>  	igt_assert(posix_memalign(&ptr, obj_size, obj_size) == 0);
>  	memset(ptr, 0, obj_size);
> @@ -710,6 +727,8 @@ static void userptr(int fd, int dir)
>  	gem_close(fd, handle);
>  	put_ahnd(ahnd);
>  	free(ptr);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static bool has_capture(int fd)
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] [PATCH v3 i-g-t 15/15] tests/i915/gem_exec_capture: Restore engines
@ 2022-01-13 23:04     ` Matthew Brost
  0 siblings, 0 replies; 71+ messages in thread
From: Matthew Brost @ 2022-01-13 23:04 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: IGT-Dev, Intel-GFX

On Thu, Jan 13, 2022 at 11:59:47AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> The test was updated some engine properties but not restoring them
> afterwards. That would leave the system in a non-default state which
> could potentially affect subsequent tests. Fix it by using the new
> save/restore engine properties helper functions.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  tests/i915/gem_exec_capture.c | 37 ++++++++++++++++++++++++++---------
>  1 file changed, 28 insertions(+), 9 deletions(-)
> 
> diff --git a/tests/i915/gem_exec_capture.c b/tests/i915/gem_exec_capture.c
> index 9beb36fc7..51db07c41 100644
> --- a/tests/i915/gem_exec_capture.c
> +++ b/tests/i915/gem_exec_capture.c
> @@ -209,14 +209,21 @@ static int check_error_state(int dir, struct offset *obj_offsets, int obj_count,
>  	return blobs;
>  }
>  
> -static void configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
> +static struct gem_engine_properties
> +configure_hangs(int fd, const struct intel_execution_engine2 *e, int ctxt_id)
>  {
> +	struct gem_engine_properties props;
> +
>  	/* Ensure fast hang detection */
> -	gem_engine_property_printf(fd, e->name, "preempt_timeout_ms", "%d", 250);
> -	gem_engine_property_printf(fd, e->name, "heartbeat_interval_ms", "%d", 500);
> +	props.engine = e;
> +	props.preempt_timeout = 250;
> +	props.heartbeat_interval = 500;
> +	gem_engine_properties_configure(fd, &props);
>  
>  	/* Allow engine based resets and disable banning */
>  	igt_allow_hang(fd, ctxt_id, HANG_ALLOW_CAPTURE | HANG_WANT_ENGINE_RESET);
> +
> +	return props;
>  }
>  
>  static bool fence_busy(int fence)
> @@ -256,8 +263,9 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	uint32_t *batch, *seqno;
>  	struct offset offset;
>  	int i, fence_out;
> +	struct gem_engine_properties saved_engine;
>  
> -	configure_hangs(fd, e, ctx->id);
> +	saved_engine = configure_hangs(fd, e, ctx->id);
>  
>  	memset(obj, 0, sizeof(obj));
>  	obj[SCRATCH].handle = gem_create_in_memory_regions(fd, 4096, region);
> @@ -371,6 +379,8 @@ static void __capture1(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	gem_close(fd, obj[BATCH].handle);
>  	gem_close(fd, obj[NOCAPTURE].handle);
>  	gem_close(fd, obj[SCRATCH].handle);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static void capture(int fd, int dir, const intel_ctx_t *ctx,
> @@ -417,8 +427,9 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  	uint32_t *batch, *seqno;
>  	struct offset *offsets;
>  	int i, fence_out;
> +	struct gem_engine_properties saved_engine;
>  
> -	configure_hangs(fd, e, ctx->id);
> +	saved_engine = configure_hangs(fd, e, ctx->id);
>  
>  	offsets = calloc(count, sizeof(*offsets));
>  	igt_assert(offsets);
> @@ -559,10 +570,12 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  
>  	qsort(offsets, count, sizeof(*offsets), cmp);
>  	igt_assert(offsets[0].addr <= offsets[count-1].addr);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  	return offsets;
>  }
>  
> -#define find_first_available_engine(fd, ctx, e) \
> +#define find_first_available_engine(fd, ctx, e, saved) \
>  	do { \
>  		ctx = intel_ctx_create_all_physical(fd); \
>  		igt_assert(ctx); \
> @@ -570,7 +583,7 @@ __captureN(int fd, int dir, uint64_t ahnd, const intel_ctx_t *ctx,
>  			for_each_if(gem_class_can_store_dword(fd, e->class)) \
>  				break; \
>  		igt_assert(e); \
> -		configure_hangs(fd, e, ctx->id); \
> +		saved = configure_hangs(fd, e, ctx->id); \
>  	} while(0)
>  
>  static void many(int fd, int dir, uint64_t size, unsigned int flags)
> @@ -580,8 +593,9 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
>  	uint64_t ram, gtt, ahnd;
>  	unsigned long count, blobs;
>  	struct offset *offsets;
> +	struct gem_engine_properties saved_engine;
>  
> -	find_first_available_engine(fd, ctx, e);
> +	find_first_available_engine(fd, ctx, e, saved_engine);
>  
>  	gtt = gem_aperture_size(fd) / size;
>  	ram = (intel_get_avail_ram_mb() << 20) / size;
> @@ -602,6 +616,8 @@ static void many(int fd, int dir, uint64_t size, unsigned int flags)
>  
>  	free(offsets);
>  	put_ahnd(ahnd);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static void prioinv(int fd, int dir, const intel_ctx_t *ctx,
> @@ -697,8 +713,9 @@ static void userptr(int fd, int dir)
>  	void *ptr;
>  	int obj_size = 4096;
>  	uint32_t system_region = INTEL_MEMORY_REGION_ID(I915_SYSTEM_MEMORY, 0);
> +	struct gem_engine_properties saved_engine;
>  
> -	find_first_available_engine(fd, ctx, e);
> +	find_first_available_engine(fd, ctx, e, saved_engine);
>  
>  	igt_assert(posix_memalign(&ptr, obj_size, obj_size) == 0);
>  	memset(ptr, 0, obj_size);
> @@ -710,6 +727,8 @@ static void userptr(int fd, int dir)
>  	gem_close(fd, handle);
>  	put_ahnd(ahnd);
>  	free(ptr);
> +
> +	gem_engine_properties_restore(fd, &saved_engine);
>  }
>  
>  static bool has_capture(int fd)
> -- 
> 2.25.1
> 

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

* Re: [igt-dev] ✗ Fi.CI.BAT: failure for Fixes for i915_hangman and gem_exec_capture (rev6)
  2022-01-13 22:53   ` Matthew Brost
@ 2022-01-13 23:15     ` John Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John Harrison @ 2022-01-13 23:15 UTC (permalink / raw)
  To: Matthew Brost, igt-dev

On 1/13/2022 14:53, Matthew Brost wrote:
> On Thu, Jan 13, 2022 at 10:23:29PM +0000, Patchwork wrote:
>> Patch Details
>>
>> Series:  Fixes for i915_hangman and gem_exec_capture (rev6)
>> URL:     https://patchwork.freedesktop.org/series/97981/
>> State:   failure
>> Details: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
>>
>> CI Bug Log - changes from CI_DRM_11080 -> IGTPW_6553
>>
>> Summary
>>
>> FAILURE
>>
>> Serious unknown changes coming with IGTPW_6553 absolutely need to be
>> verified manually.
>>
>> If you think the reported changes have nothing to do with the changes
>> introduced in IGTPW_6553, please notify your bug team to allow them
>> to document this new failure mode, which will reduce false positives in CI.
>>
>> External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
>>
>> Participating hosts (41 -> 41)
>>
>> Additional (1): fi-kbl-soraka
>> Missing (1): fi-bsw-cyan
>>
>> Possible new issues
>>
>> Here are the unknown changes that may have been introduced in IGTPW_6553:
>>
>> IGT changes
>>
>> Possible regressions
>>
>>    • igt@i915_hangman@error-state-basic:
>>        □ bat-dg1-6: PASS -> SKIP
> It looks like it is skipped because of the requirement:
> Test requirement not met in function __igt_unique____real_main495, file ../tests/i915/i915_hangman.c:517:
> Test requirement: gem_mmap__has_wc(device)
>
> Which was added in this patch:
> https://patchwork.freedesktop.org/patch/469465/?series=97981&rev=6
>
>   static void do_tests(const char *name, const char *prefix,
> @@ -433,6 +490,8 @@  igt_main
>   		igt_assert(sysfs != -1);
>   
>   		igt_require(has_error_state(sysfs));
> +
> +		gem_require_mmap_wc(device);
>   	}
>   
>   	igt_describe("Basic error capture");
>
> Do discrete device not support mmap_wc?
>
> Matt
It seemed to be working on a DG2 with an internal kernel. But for 
upstream, it looks like we need to use _device_coherent instead of _wc 
for the require and the actual mmap calls. About to post an updated patch...

John.

>
>> Known issues
>>
>> Here are the changes found in IGTPW_6553 that come from known issues:
>>
>> IGT changes
>>
>> Issues hit
>>
>>    • igt@amdgpu/amd_cs_nop@sync-fork-compute0:
>>
>>        □ fi-snb-2600: NOTRUN -> SKIP (fdo#109271) +17 similar issues
>>    • igt@gem_exec_fence@basic-busy@bcs0:
>>
>>        □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271) +8 similar issues
>>    • igt@gem_huc_copy@huc-copy:
>>
>>        □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#2190)
>>
>>        □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#2190)
>>
>>    • igt@gem_lmem_swapping@basic:
>>
>>        □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#4613) +3 similar
>>          issues
>>    • igt@gem_lmem_swapping@verify-random:
>>
>>        □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#4613) +3 similar issues
>>    • igt@i915_pm_rps@basic-api:
>>
>>        □ bat-dg1-6: PASS -> FAIL (i915#4032)
>>    • igt@i915_selftest@live:
>>
>>        □ fi-skl-6600u: NOTRUN -> INCOMPLETE (i915#4794)
>>    • igt@i915_selftest@live@gt_pm:
>>
>>        □ fi-kbl-soraka: NOTRUN -> DMESG-FAIL (i915#1886 / i915#2291)
>>    • igt@i915_selftest@live@requests:
>>
>>        □ fi-blb-e6850: PASS -> DMESG-FAIL (i915#4528)
>>    • igt@kms_chamelium@common-hpd-after-suspend:
>>
>>        □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / fdo#111827) +8 similar
>>          issues
>>    • igt@kms_chamelium@vga-edid-read:
>>
>>        □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / fdo#111827) +8 similar
>>          issues
>>    • igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
>>
>>        □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271) +3 similar issues
>>    • igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
>>
>>        □ fi-skl-6600u: NOTRUN -> SKIP (fdo#109271 / i915#533)
>>
>>        □ fi-kbl-soraka: NOTRUN -> SKIP (fdo#109271 / i915#533)
>>
>>    • igt@runner@aborted:
>>
>>        □ fi-blb-e6850: NOTRUN -> FAIL (fdo#109271 / i915#2403 / i915#4312)
>>
>> Possible fixes
>>
>>    • igt@gem_exec_suspend@basic-s3@smem:
>>
>>        □ fi-skl-6600u: INCOMPLETE (i915#4547) -> PASS
>>    • igt@i915_selftest@live@execlists:
>>
>>        □ {bat-jsl-1}: DMESG-FAIL -> PASS
>>    • igt@i915_selftest@live@hangcheck:
>>
>>        □ fi-snb-2600: INCOMPLETE (i915#3921) -> PASS
>>
>> {name}: This element is suppressed. This means it is ignored when computing
>> the status of the difference (SUCCESS, WARNING, or FAILURE).
>>
>> Build changes
>>
>>    • CI: CI-20190529 -> None
>>    • IGT: IGT_6326 -> IGTPW_6553
>>
>> CI-20190529: 20190529
>> CI_DRM_11080: 8f2355c95e279e57a962843e5d7ba38885b3cfb7 @ git://
>> anongit.freedesktop.org/gfx-ci/linux
>> IGTPW_6553: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_6553/index.html
>> IGT_6326: ec75f64fcbcf4aac58fbf1bf629e8f59b19db4ce @ https://
>> gitlab.freedesktop.org/drm/igt-gpu-tools.git
>>
>> == Testlist changes ==
>>
>> +igt@i915_hangman@detector
>> +igt@i915_hangman@engine-engine-error
>> +igt@i915_hangman@engine-engine-hang
>> +igt@i915_hangman@engine-error-state-capture
>> +igt@i915_hangman@gt-engine-error
>> +igt@i915_hangman@gt-engine-hang
>> +igt@i915_hangman@gt-error-state-capture
>> -igt@i915_hangman@engine-error
>> -igt@i915_hangman@engine-hang
>> -igt@i915_hangman@error-state-capture
>>
>> SECURITY NOTE: file ~/.netrc must not be accessible by others

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

* [Intel-gfx] [PATCH i-g-t] tests/i915/i915_hangman: Add alive-ness test after error capture
  2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
@ 2022-01-13 23:24     ` John.C.Harrison
  -1 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 23:24 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added a an extra step to the i915_hangman tests to check that the
system is still alive after the hang and recovery. This submits a
simple batch to each engine which does a write to memory and checks
that the write occurred.

v2: Use _device_coherent instead of _wc for mapping memory to support
discrete boards.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
---
 tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 5a0c9497c..73a86ec9e 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -48,8 +48,57 @@
 static int device = -1;
 static int sysfs = -1;
 
+#define OFFSET_ALIVE	10
+
 IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
 
+static void check_alive(void)
+{
+	const struct intel_execution_engine2 *engine;
+	const intel_ctx_t *ctx;
+	uint32_t scratch, *out;
+	int fd, i = 0;
+	uint64_t ahnd, scratch_addr;
+
+	fd = drm_open_driver(DRIVER_INTEL);
+	igt_require(gem_class_can_store_dword(fd, 0));
+
+	ctx = intel_ctx_create_all_physical(fd);
+	ahnd = get_reloc_ahnd(fd, ctx->id);
+	scratch = gem_create(fd, 4096);
+	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
+	out = gem_mmap__device_coherent(fd, scratch, 0, 4096, PROT_WRITE | PROT_READ);
+	gem_set_domain(fd, scratch,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	for_each_physical_engine(fd, engine) {
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
+		i++;
+	}
+
+	i = 0;
+	for_each_ctx_engine(fd, ctx, engine) {
+		if (!gem_class_can_store_dword(fd, engine->class))
+			continue;
+
+		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
+		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
+			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
+		i++;
+	}
+
+	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
+
+	while (i--)
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
+
+	munmap(out, 4096);
+	gem_close(fd, scratch);
+	put_ahnd(ahnd);
+	intel_ctx_destroy(fd, ctx);
+	close(fd);
+}
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static void
@@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
 		put_ahnd(ahndN);
 	}
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static int hang_count;
@@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
 
 	/* Did it work? */
 	igt_assert(hang_count == 1);
+
+	check_alive();
 }
 
 /* This test covers the case where we end up in an uninitialised area of the
@@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 		igt_force_gpu_reset(device);
 		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
+
+	check_alive();
 }
 
 static void do_tests(const char *name, const char *prefix,
@@ -433,6 +490,8 @@ igt_main
 		igt_assert(sysfs != -1);
 
 		igt_require(has_error_state(sysfs));
+
+		gem_require_mmap_device_coherent(device);
 	}
 
 	igt_describe("Basic error capture");
-- 
2.25.1


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

* [igt-dev] [PATCH i-g-t] tests/i915/i915_hangman: Add alive-ness test after error capture
@ 2022-01-13 23:24     ` John.C.Harrison
  0 siblings, 0 replies; 71+ messages in thread
From: John.C.Harrison @ 2022-01-13 23:24 UTC (permalink / raw)
  To: IGT-Dev; +Cc: Intel-GFX

From: John Harrison <John.C.Harrison@Intel.com>

Added a an extra step to the i915_hangman tests to check that the
system is still alive after the hang and recovery. This submits a
simple batch to each engine which does a write to memory and checks
that the write occurred.

v2: Use _device_coherent instead of _wc for mapping memory to support
discrete boards.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
---
 tests/i915/i915_hangman.c | 59 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tests/i915/i915_hangman.c b/tests/i915/i915_hangman.c
index 5a0c9497c..73a86ec9e 100644
--- a/tests/i915/i915_hangman.c
+++ b/tests/i915/i915_hangman.c
@@ -48,8 +48,57 @@
 static int device = -1;
 static int sysfs = -1;
 
+#define OFFSET_ALIVE	10
+
 IGT_TEST_DESCRIPTION("Tests for hang detection and recovery");
 
+static void check_alive(void)
+{
+	const struct intel_execution_engine2 *engine;
+	const intel_ctx_t *ctx;
+	uint32_t scratch, *out;
+	int fd, i = 0;
+	uint64_t ahnd, scratch_addr;
+
+	fd = drm_open_driver(DRIVER_INTEL);
+	igt_require(gem_class_can_store_dword(fd, 0));
+
+	ctx = intel_ctx_create_all_physical(fd);
+	ahnd = get_reloc_ahnd(fd, ctx->id);
+	scratch = gem_create(fd, 4096);
+	scratch_addr = get_offset(ahnd, scratch, 4096, 0);
+	out = gem_mmap__device_coherent(fd, scratch, 0, 4096, PROT_WRITE | PROT_READ);
+	gem_set_domain(fd, scratch,
+			I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+
+	for_each_physical_engine(fd, engine) {
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], 0);
+		i++;
+	}
+
+	i = 0;
+	for_each_ctx_engine(fd, ctx, engine) {
+		if (!gem_class_can_store_dword(fd, engine->class))
+			continue;
+
+		/* +OFFSET_ALIVE to ensure engine zero doesn't get a false negative */
+		igt_store_word(fd, ahnd, ctx, engine, -1, scratch, scratch_addr,
+			       i + OFFSET_ALIVE, i + OFFSET_ALIVE);
+		i++;
+	}
+
+	gem_set_domain(fd, scratch, I915_GEM_DOMAIN_GTT, 0);
+
+	while (i--)
+		igt_assert_eq_u32(out[i + OFFSET_ALIVE], i + OFFSET_ALIVE);
+
+	munmap(out, 4096);
+	gem_close(fd, scratch);
+	put_ahnd(ahnd);
+	intel_ctx_destroy(fd, ctx);
+	close(fd);
+}
+
 static bool has_error_state(int dir)
 {
 	bool result;
@@ -231,6 +280,8 @@ static void test_error_state_capture(const intel_ctx_t *ctx,
 	check_error_state(e->name, offset, batch);
 	munmap(batch, 4096);
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static void
@@ -289,6 +340,8 @@ test_engine_hang(const intel_ctx_t *ctx,
 		put_ahnd(ahndN);
 	}
 	put_ahnd(ahnd);
+
+	check_alive();
 }
 
 static int hang_count;
@@ -321,6 +374,8 @@ static void test_hang_detector(const intel_ctx_t *ctx,
 
 	/* Did it work? */
 	igt_assert(hang_count == 1);
+
+	check_alive();
 }
 
 /* This test covers the case where we end up in an uninitialised area of the
@@ -356,6 +411,8 @@ static void hangcheck_unterminated(const intel_ctx_t *ctx)
 		igt_force_gpu_reset(device);
 		igt_assert_f(0, "unterminated batch did not trigger a hang!\n");
 	}
+
+	check_alive();
 }
 
 static void do_tests(const char *name, const char *prefix,
@@ -433,6 +490,8 @@ igt_main
 		igt_assert(sysfs != -1);
 
 		igt_require(has_error_state(sysfs));
+
+		gem_require_mmap_device_coherent(device);
 	}
 
 	igt_describe("Basic error capture");
-- 
2.25.1

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

* [igt-dev] ✗ Fi.CI.BUILD: failure for Fixes for i915_hangman and gem_exec_capture (rev7)
  2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
                   ` (16 preceding siblings ...)
  (?)
@ 2022-01-13 23:25 ` Patchwork
  -1 siblings, 0 replies; 71+ messages in thread
From: Patchwork @ 2022-01-13 23:25 UTC (permalink / raw)
  To: john.c.harrison; +Cc: igt-dev

== Series Details ==

Series: Fixes for i915_hangman and gem_exec_capture (rev7)
URL   : https://patchwork.freedesktop.org/series/97981/
State : failure

== Summary ==

Applying: tests/i915/i915_hangman: Add descriptions
Applying: lib/hang: Fix igt_require_hang_ring to work with all engines
Applying: tests/i915/i915_hangman: Update capture test to use engine structure
Applying: tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU reset
Applying: tests/i915/i915_hangman: Add uevent test & fix detector
Applying: tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated
Applying: lib/store: Refactor common store code into helper function
Applying: tests/i915/i915_hangman: Add alive-ness test after error capture
Applying: tests/i915/i915_hangman: Remove reliance on context persistance
Applying: tests/i915/i915_hangman: Run background task on all engines
Applying: tests/i915/i915_hangman: Don't let background contexts cause a ban
Applying: tests/i915/gem_exec_fence: Configure correct context
Applying: lib/i915: Add helper for non-destructive engine property updates
Applying: tests/i915/i915_hangman: Configure engine properties for quicker hangs
Using index info to reconstruct a base tree...
M	tests/i915/i915_hangman.c
Falling back to patching base and 3-way merge...
Auto-merging tests/i915/i915_hangman.c
CONFLICT (content): Merge conflict in tests/i915/i915_hangman.c
Patch failed at 0014 tests/i915/i915_hangman: Configure engine properties for quicker hangs
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


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

end of thread, other threads:[~2022-01-13 23:25 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-13 19:59 [Intel-gfx] [PATCH v3 i-g-t 00/15] Fixes for i915_hangman and gem_exec_capture John.C.Harrison
2022-01-13 19:59 ` [igt-dev] " John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 01/15] tests/i915/i915_hangman: Add descriptions John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 02/15] lib/hang: Fix igt_require_hang_ring to work with all engines John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 03/15] tests/i915/i915_hangman: Update capture test to use engine structure John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 19:58   ` [Intel-gfx] " Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 04/15] tests/i915/i915_hangman: Explicitly test per engine reset vs full GPU reset John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 05/15] tests/i915/i915_hangman: Add uevent test & fix detector John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 06/15] tests/i915/i915_hangman: Use the correct context in hangcheck_unterminated John.C.Harrison
2022-01-13 20:00   ` Matthew Brost
2022-01-13 20:00     ` [igt-dev] " Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 07/15] lib/store: Refactor common store code into helper function John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 20:10   ` [Intel-gfx] " Matthew Brost
2022-01-13 20:27     ` John Harrison
2022-01-13 20:27       ` John Harrison
2022-01-13 20:23       ` [Intel-gfx] " Matthew Brost
2022-01-13 20:23         ` Matthew Brost
2022-01-13 20:40         ` [Intel-gfx] " John Harrison
2022-01-13 20:40           ` John Harrison
2022-01-13 20:50   ` [Intel-gfx] [PATCH i-g-t] " John.C.Harrison
2022-01-13 20:50     ` [igt-dev] " John.C.Harrison
2022-01-13 20:53     ` [Intel-gfx] " Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 08/15] tests/i915/i915_hangman: Add alive-ness test after error capture John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 20:18   ` [Intel-gfx] " Matthew Brost
2022-01-13 20:18     ` [igt-dev] " Matthew Brost
2022-01-13 23:24   ` [Intel-gfx] [PATCH i-g-t] " John.C.Harrison
2022-01-13 23:24     ` [igt-dev] " John.C.Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 09/15] tests/i915/i915_hangman: Remove reliance on context persistance John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 20:30   ` [Intel-gfx] " Matthew Brost
2022-01-13 20:30     ` Matthew Brost
2022-01-13 20:42     ` [Intel-gfx] " John Harrison
2022-01-13 20:38       ` Matthew Brost
2022-01-13 20:38         ` Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 10/15] tests/i915/i915_hangman: Run background task on all engines John.C.Harrison
2022-01-13 20:48   ` Matthew Brost
2022-01-13 20:48     ` [igt-dev] " Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 11/15] tests/i915/i915_hangman: Don't let background contexts cause a ban John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 21:01   ` [Intel-gfx] " Matthew Brost
2022-01-13 21:01     ` Matthew Brost
2022-01-13 21:19     ` [Intel-gfx] " John Harrison
2022-01-13 21:19       ` John Harrison
2022-01-13 21:26   ` [Intel-gfx] [PATCH i-g-t] " John.C.Harrison
2022-01-13 22:30     ` Matthew Brost
2022-01-13 22:30       ` [igt-dev] " Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 12/15] tests/i915/gem_exec_fence: Configure correct context John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 21:06   ` [Intel-gfx] " Matthew Brost
2022-01-13 21:23     ` John Harrison
2022-01-13 21:23       ` John Harrison
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 13/15] lib/i915: Add helper for non-destructive engine property updates John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 22:33   ` [Intel-gfx] " Matthew Brost
2022-01-13 22:33     ` Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 14/15] tests/i915/i915_hangman: Configure engine properties for quicker hangs John.C.Harrison
2022-01-13 22:38   ` Matthew Brost
2022-01-13 19:59 ` [Intel-gfx] [PATCH v3 i-g-t 15/15] tests/i915/gem_exec_capture: Restore engines John.C.Harrison
2022-01-13 19:59   ` [igt-dev] " John.C.Harrison
2022-01-13 23:04   ` [Intel-gfx] " Matthew Brost
2022-01-13 23:04     ` Matthew Brost
2022-01-13 22:23 ` [igt-dev] ✗ Fi.CI.BAT: failure for Fixes for i915_hangman and gem_exec_capture (rev6) Patchwork
2022-01-13 22:53   ` Matthew Brost
2022-01-13 23:15     ` John Harrison
2022-01-13 23:25 ` [igt-dev] ✗ Fi.CI.BUILD: failure for Fixes for i915_hangman and gem_exec_capture (rev7) Patchwork

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.