diff mbox

[i-g-t] lib/gt: Make use of dummyload library to create recursive batch

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

Commit Message

Chris Wilson July 13, 2018, 10:06 a.m. UTC
From: Antonio Argenziano <antonio.argenziano@intel.com>

An hanging batch is nothing more than a spinning batch that never gets
stopped, so re-use the routines implemented in dummyload.c.

v2: Let caller decide spin loop size
v3: Only use loose loops for hangs (Chris)
v4: No requires
v5: Free the spinner
v6: Chamelium exists.

Signed-off-by: Antonio Argenziano <antonio.argenziano@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 lib/i915/gem_ring.c        |   1 +
 lib/igt_aux.h              | 105 ------------------------------
 lib/igt_chamelium.c        |   3 +-
 lib/igt_core.h             |   4 ++
 lib/igt_dummyload.h        |   3 +-
 lib/igt_gt.c               |  72 ++++-----------------
 lib/igt_gt.h               |   9 +--
 lib/igt_kmod.c             |   3 +-
 lib/igt_kmod.h             |   2 +-
 lib/igt_list.h             | 128 +++++++++++++++++++++++++++++++++++++
 tests/drv_hangman.c        |   9 ++-
 tests/gem_concurrent_all.c |  23 ++-----
 tests/gem_exec_schedule.c  |   4 +-
 tests/gem_mmap_gtt.c       |   2 +-
 tests/gem_reset_stats.c    |   4 +-
 tests/gem_shrink.c         |   2 +-
 tests/gem_softpin.c        |   7 +-
 17 files changed, 177 insertions(+), 204 deletions(-)
 create mode 100644 lib/igt_list.h

Comments

Antonio Argenziano July 13, 2018, 6:22 p.m. UTC | #1
On 13/07/18 03:06, Chris Wilson wrote:
> From: Antonio Argenziano <antonio.argenziano@intel.com>
> 
> An hanging batch is nothing more than a spinning batch that never gets
> stopped, so re-use the routines implemented in dummyload.c.
> 
> v2: Let caller decide spin loop size
> v3: Only use loose loops for hangs (Chris)
> v4: No requires
> v5: Free the spinner
> v6: Chamelium exists.
> 
> Signed-off-by: Antonio Argenziano <antonio.argenziano@intel.com>
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---

>   /**
> @@ -377,11 +329,11 @@ igt_hang_t igt_hang_ring(int fd, int ring)
>    */
>   void igt_post_hang_ring(int fd, igt_hang_t arg)
>   {
> -	if (arg.handle == 0)
> +	if (!arg.spin)
>   		return;
>   
> -	gem_sync(fd, arg.handle);
> -	gem_close(fd, arg.handle);
> +	gem_sync(fd, arg.spin->handle); /* Wait until it hangs */

I was expecting a poll spinner + manual reset here.

> +	igt_spin_batch_free(fd, arg.spin);
>   
>   	context_set_ban(fd, arg.ctx, arg.ban);
>   
> diff --git a/lib/igt_gt.h b/lib/igt_gt.h

> +
> +#define igt_list_for_each_safe(pos, tmp, head, member)			\

(nitpick) extra tab.

> +	for (pos = igt_list_first_entry(head, pos, member),		\
> +	     tmp = igt_list_next_entry(pos, member);			\

I trust you and the compiler got all the places that needed changing.

Reviewed-by: Antonio Argenziano <antonio.argenziano@intel.com>

Thanks for picking-up this. At my speed it would have taken years :).
Chris Wilson July 13, 2018, 6:28 p.m. UTC | #2
Quoting Antonio Argenziano (2018-07-13 19:22:41)
> 
> 
> On 13/07/18 03:06, Chris Wilson wrote:
> > From: Antonio Argenziano <antonio.argenziano@intel.com>
> > 
> > An hanging batch is nothing more than a spinning batch that never gets
> > stopped, so re-use the routines implemented in dummyload.c.
> > 
> > v2: Let caller decide spin loop size
> > v3: Only use loose loops for hangs (Chris)
> > v4: No requires
> > v5: Free the spinner
> > v6: Chamelium exists.
> > 
> > Signed-off-by: Antonio Argenziano <antonio.argenziano@intel.com>
> > Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> > ---
> 
> >   /**
> > @@ -377,11 +329,11 @@ igt_hang_t igt_hang_ring(int fd, int ring)
> >    */
> >   void igt_post_hang_ring(int fd, igt_hang_t arg)
> >   {
> > -     if (arg.handle == 0)
> > +     if (!arg.spin)
> >               return;
> >   
> > -     gem_sync(fd, arg.handle);
> > -     gem_close(fd, arg.handle);
> > +     gem_sync(fd, arg.spin->handle); /* Wait until it hangs */
> 
> I was expecting a poll spinner + manual reset here.

That would break some tests that are using this for hangcheck.
(Not break as such, just make them not work as intended.) More refinement
required, there's room for plenty here!

> 
> > +     igt_spin_batch_free(fd, arg.spin);
> >   
> >       context_set_ban(fd, arg.ctx, arg.ban);
> >   
> > diff --git a/lib/igt_gt.h b/lib/igt_gt.h
> 
> > +
> > +#define igt_list_for_each_safe(pos, tmp, head, member)                       \
> 
> (nitpick) extra tab.

So much for just moving it to a new header :)

> > +     for (pos = igt_list_first_entry(head, pos, member),             \
> > +          tmp = igt_list_next_entry(pos, member);                    \
> 
> I trust you and the compiler got all the places that needed changing.
> 
> Reviewed-by: Antonio Argenziano <antonio.argenziano@intel.com>
> 
> Thanks for picking-up this. At my speed it would have taken years :).

The task is only just begun.
-Sisyphus
diff mbox

Patch

diff --git a/lib/i915/gem_ring.c b/lib/i915/gem_ring.c
index 0708c8a2e..fdb9fc1b1 100644
--- a/lib/i915/gem_ring.c
+++ b/lib/i915/gem_ring.c
@@ -25,6 +25,7 @@ 
 
 #include <signal.h>
 #include <sys/ioctl.h>
+#include <sys/time.h>
 
 #include "intel_reg.h"
 #include "drmtest.h"
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index 9a962881b..639a90778 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -31,7 +31,6 @@ 
 #include <intel_bufmgr.h>
 #include <inttypes.h>
 #include <stdbool.h>
-#include <stddef.h>
 #include <sys/time.h>
 
 #include <i915/gem_submission.h>
@@ -39,12 +38,6 @@ 
 extern drm_intel_bo **trash_bos;
 extern int num_trash_bos;
 
-/* signal interrupt helpers */
-
-#define MSEC_PER_SEC (1000)
-#define USEC_PER_SEC (1000*MSEC_PER_SEC)
-#define NSEC_PER_SEC (1000*USEC_PER_SEC)
-
 /* signal interrupt helpers */
 #define gettid() syscall(__NR_gettid)
 #define sigev_notify_thread_id _sigev_un._tid
@@ -295,104 +288,6 @@  void igt_set_module_param_int(const char *name, int val);
 int igt_terminate_process(int sig, const char *comm);
 void igt_lsof(const char *dpath);
 
-/*
- * This list data structure is a verbatim copy from wayland-util.h from the
- * Wayland project; except that wl_ prefix has been removed.
- */
-
-struct igt_list {
-	struct igt_list *prev;
-	struct igt_list *next;
-};
-
-#define __IGT_INIT_LIST(name) { &(name), &(name) }
-#define IGT_LIST(name) struct igt_list name = __IGT_INIT_LIST(name)
-
-static inline void igt_list_init(struct igt_list *list)
-{
-	list->prev = list;
-	list->next = list;
-}
-
-static inline void __igt_list_add(struct igt_list *list,
-				  struct igt_list *prev,
-				  struct igt_list *next)
-{
-	next->prev = list;
-	list->next = next;
-	list->prev = prev;
-	prev->next = list;
-}
-
-static inline void igt_list_add(struct igt_list *elm, struct igt_list *list)
-{
-	__igt_list_add(elm, list, list->next);
-}
-
-static inline void igt_list_add_tail(struct igt_list *elm,
-				     struct igt_list *list)
-{
-	__igt_list_add(elm, list->prev, list);
-}
-
-static inline void __igt_list_del(struct igt_list *prev, struct igt_list *next)
-{
-	next->prev = prev;
-	prev->next = next;
-}
-
-static inline void igt_list_del(struct igt_list *elm)
-{
-	__igt_list_del(elm->prev, elm->next);
-}
-
-static inline void igt_list_move(struct igt_list *elm, struct igt_list *list)
-{
-	igt_list_del(elm);
-	igt_list_add(elm, list);
-}
-
-static inline void igt_list_move_tail(struct igt_list *elm,
-				      struct igt_list *list)
-{
-	igt_list_del(elm);
-	igt_list_add_tail(elm, list);
-}
-
-static inline bool igt_list_empty(const struct igt_list *list)
-{
-	return list->next == list;
-}
-
-#define container_of(ptr, sample, member)				\
-	(typeof(sample))((char *)(ptr) - offsetof(typeof(*sample), member))
-
-#define igt_list_first_entry(head, pos, member) \
-	container_of((head)->next, (pos), member)
-#define igt_list_last_entry(head, pos, member) \
-	container_of((head)->prev, (pos), member)
-
-#define igt_list_next_entry(pos, member) \
-	container_of((pos)->member.next, (pos), member)
-#define igt_list_prev_entry(pos, member) \
-	container_of((pos)->member.prev, (pos), member)
-
-#define igt_list_for_each(pos, head, member)				\
-	for (pos = igt_list_first_entry(head, pos, member);		\
-	     &pos->member != (head);					\
-	     pos = igt_list_next_entry(pos, member))
-
-#define igt_list_for_each_reverse(pos, head, member)			\
-	for (pos = igt_list_last_entry(head, pos, member);		\
-	     &pos->member != (head);					\
-	     pos = igt_list_prev_entry(pos, member))
-
-#define igt_list_for_each_safe(pos, tmp, head, member)			\
-	for (pos = igt_list_first_entry(head, pos, member),		\
-	     tmp = igt_list_next_entry(pos, member);			\
-	     &pos->member != (head);					\
-	     pos = tmp, tmp = igt_list_next_entry(pos, member))
-
 #define igt_hweight(x) \
 	__builtin_choose_expr(sizeof(x) == 8, \
 			      __builtin_popcountll(x), \
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index b25855a41..b8418e13e 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -38,8 +38,9 @@ 
 #include "igt_chamelium.h"
 #include "igt_core.h"
 #include "igt_aux.h"
-#include "igt_kms.h"
 #include "igt_frame.h"
+#include "igt_list.h"
+#include "igt_kms.h"
 #include "igt_rc.h"
 
 /**
diff --git a/lib/igt_core.h b/lib/igt_core.h
index a73b06493..aaf1b6268 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -1005,4 +1005,8 @@  void igt_kmsg(const char *format, ...);
 
 #define READ_ONCE(x) (*(volatile typeof(x) *)(&(x)))
 
+#define MSEC_PER_SEC (1000)
+#define USEC_PER_SEC (1000*MSEC_PER_SEC)
+#define NSEC_PER_SEC (1000*USEC_PER_SEC)
+
 #endif /* IGT_CORE_H */
diff --git a/lib/igt_dummyload.h b/lib/igt_dummyload.h
index 38bc7682e..73bd035b4 100644
--- a/lib/igt_dummyload.h
+++ b/lib/igt_dummyload.h
@@ -28,7 +28,8 @@ 
 #include <stdint.h>
 #include <time.h>
 
-#include "igt_aux.h"
+#include "igt_core.h"
+#include "igt_list.h"
 #include "i915_drm.h"
 
 typedef struct igt_spin {
diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 89b318ae6..a20619246 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -40,6 +40,7 @@ 
 #include "ioctl_wrappers.h"
 #include "intel_reg.h"
 #include "intel_chipset.h"
+#include "igt_dummyload.h"
 
 /**
  * SECTION:igt_gt
@@ -265,20 +266,11 @@  static bool has_ctx_exec(int fd, unsigned ring, uint32_t ctx)
  * Returns:
  * Structure with helper internal state for igt_post_hang_ring().
  */
-igt_hang_t igt_hang_ctx(int fd,
-			uint32_t ctx,
-			int ring,
-			unsigned flags,
-			uint64_t *offset)
+igt_hang_t igt_hang_ctx(int fd, uint32_t ctx, int ring, unsigned flags)
 {
-	struct drm_i915_gem_relocation_entry reloc;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	struct drm_i915_gem_exec_object2 exec;
 	struct drm_i915_gem_context_param param;
-	uint32_t b[16];
+	igt_spin_t *spin;
 	unsigned ban;
-	unsigned len;
-	int gen;
 
 	igt_require_hang_ring(fd, ring);
 
@@ -302,52 +294,12 @@  igt_hang_t igt_hang_ctx(int fd,
 	if ((flags & HANG_ALLOW_BAN) == 0)
 		context_set_ban(fd, ctx, 0);
 
-	memset(&reloc, 0, sizeof(reloc));
-	memset(&exec, 0, sizeof(exec));
-	memset(&execbuf, 0, sizeof(execbuf));
-
-	exec.handle = gem_create(fd, 4096);
-	exec.relocation_count = 1;
-	exec.relocs_ptr = to_user_pointer(&reloc);
-
-	memset(b, 0xc5, sizeof(b));
-
-	len = 0;
-	gen = intel_gen(intel_get_drm_devid(fd));
-	if (gen >= 8) {
-		b[len++] = MI_BATCH_BUFFER_START | 1 << 8 | 1;
-		b[len++] = 0;
-		b[len++] = 0;
-	} else if (gen >= 6) {
-		b[len++] = MI_BATCH_BUFFER_START | 1 << 8;
-		b[len++] = 0;
-	} else {
-		b[len++] = MI_BATCH_BUFFER_START | 2 << 6;
-		b[len] = 0;
-		if (gen < 4) {
-			b[len] |= 1;
-			reloc.delta = 1;
-		}
-		len++;
-	}
-	b[len++] = MI_BATCH_BUFFER_END;
-	b[len] = MI_NOOP;
-	gem_write(fd, exec.handle, 0, b, sizeof(b));
-
-	reloc.offset = sizeof(uint32_t);
-	reloc.target_handle = exec.handle;
-	reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
-
-	execbuf.buffers_ptr = to_user_pointer(&exec);
-	execbuf.buffer_count = 1;
-	execbuf.flags = ring;
-	i915_execbuffer2_set_context_id(execbuf, ctx);
-	gem_execbuf(fd, &execbuf);
-
-	if (offset)
-		*offset = exec.offset;
+	spin = __igt_spin_batch_new(fd,
+				    .ctx = ctx,
+				    .engine = ring,
+				    .flags = IGT_SPIN_NO_PREEMPTION);
 
-	return (igt_hang_t){ exec.handle, ctx, ban, flags };
+	return (igt_hang_t){ spin, ctx, ban, flags };
 }
 
 /**
@@ -364,7 +316,7 @@  igt_hang_t igt_hang_ctx(int fd,
  */
 igt_hang_t igt_hang_ring(int fd, int ring)
 {
-	return igt_hang_ctx(fd, 0, ring, 0, NULL);
+	return igt_hang_ctx(fd, 0, ring, 0);
 }
 
 /**
@@ -377,11 +329,11 @@  igt_hang_t igt_hang_ring(int fd, int ring)
  */
 void igt_post_hang_ring(int fd, igt_hang_t arg)
 {
-	if (arg.handle == 0)
+	if (!arg.spin)
 		return;
 
-	gem_sync(fd, arg.handle);
-	gem_close(fd, arg.handle);
+	gem_sync(fd, arg.spin->handle); /* Wait until it hangs */
+	igt_spin_batch_free(fd, arg.spin);
 
 	context_set_ban(fd, arg.ctx, arg.ban);
 
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index d44b7552f..54e95da98 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -25,6 +25,7 @@ 
 #define IGT_GT_H
 
 #include "igt_debugfs.h"
+#include "igt_dummyload.h"
 #include "igt_core.h"
 
 #include "i915_drm.h"
@@ -32,7 +33,7 @@ 
 void igt_require_hang_ring(int fd, int ring);
 
 typedef struct igt_hang {
-	unsigned handle;
+	igt_spin_t *spin;
 	unsigned ctx;
 	unsigned ban;
 	unsigned flags;
@@ -43,11 +44,7 @@  void igt_disallow_hang(int fd, igt_hang_t arg);
 
 #define HANG_POISON 0xc5c5c5c5
 
-igt_hang_t igt_hang_ctx(int fd,
-			uint32_t ctx,
-			int ring,
-			unsigned flags,
-			uint64_t *offset);
+igt_hang_t igt_hang_ctx(int fd, uint32_t ctx, int ring, unsigned flags);
 #define HANG_ALLOW_BAN 1
 #define HANG_ALLOW_CAPTURE 2
 
diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c
index f3f34a62d..b2f4f884b 100644
--- a/lib/igt_kmod.c
+++ b/lib/igt_kmod.c
@@ -24,9 +24,10 @@ 
 #include <signal.h>
 #include <errno.h>
 
+#include "igt_aux.h"
 #include "igt_core.h"
-#include "igt_sysfs.h"
 #include "igt_kmod.h"
+#include "igt_sysfs.h"
 
 /**
  * SECTION:igt_kmod
diff --git a/lib/igt_kmod.h b/lib/igt_kmod.h
index fd307a456..87d36d400 100644
--- a/lib/igt_kmod.h
+++ b/lib/igt_kmod.h
@@ -26,7 +26,7 @@ 
 
 #include <libkmod.h>
 
-#include "igt_aux.h"
+#include "igt_list.h"
 
 bool igt_kmod_is_loaded(const char *mod_name);
 void igt_kmod_list_loaded(void);
diff --git a/lib/igt_list.h b/lib/igt_list.h
new file mode 100644
index 000000000..744f4ecf9
--- /dev/null
+++ b/lib/igt_list.h
@@ -0,0 +1,128 @@ 
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef IGT_LIST_H
+#define IGT_LIST_H
+
+#include <stddef.h>
+
+/*
+ * This list data structure is a verbatim copy from wayland-util.h from the
+ * Wayland project; except that wl_ prefix has been removed.
+ */
+
+struct igt_list {
+	struct igt_list *prev;
+	struct igt_list *next;
+};
+
+#define __IGT_INIT_LIST(name) { &(name), &(name) }
+#define IGT_LIST(name) struct igt_list name = __IGT_INIT_LIST(name)
+
+static inline void igt_list_init(struct igt_list *list)
+{
+	list->prev = list;
+	list->next = list;
+}
+
+static inline void __igt_list_add(struct igt_list *list,
+				  struct igt_list *prev,
+				  struct igt_list *next)
+{
+	next->prev = list;
+	list->next = next;
+	list->prev = prev;
+	prev->next = list;
+}
+
+static inline void igt_list_add(struct igt_list *elm, struct igt_list *list)
+{
+	__igt_list_add(elm, list, list->next);
+}
+
+static inline void igt_list_add_tail(struct igt_list *elm,
+				     struct igt_list *list)
+{
+	__igt_list_add(elm, list->prev, list);
+}
+
+static inline void __igt_list_del(struct igt_list *prev, struct igt_list *next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+static inline void igt_list_del(struct igt_list *elm)
+{
+	__igt_list_del(elm->prev, elm->next);
+}
+
+static inline void igt_list_move(struct igt_list *elm, struct igt_list *list)
+{
+	igt_list_del(elm);
+	igt_list_add(elm, list);
+}
+
+static inline void igt_list_move_tail(struct igt_list *elm,
+				      struct igt_list *list)
+{
+	igt_list_del(elm);
+	igt_list_add_tail(elm, list);
+}
+
+static inline bool igt_list_empty(const struct igt_list *list)
+{
+	return list->next == list;
+}
+
+#define container_of(ptr, sample, member)				\
+	(typeof(sample))((char *)(ptr) - offsetof(typeof(*sample), member))
+
+#define igt_list_first_entry(head, pos, member) \
+	container_of((head)->next, (pos), member)
+#define igt_list_last_entry(head, pos, member) \
+	container_of((head)->prev, (pos), member)
+
+#define igt_list_next_entry(pos, member) \
+	container_of((pos)->member.next, (pos), member)
+#define igt_list_prev_entry(pos, member) \
+	container_of((pos)->member.prev, (pos), member)
+
+#define igt_list_for_each(pos, head, member)				\
+	for (pos = igt_list_first_entry(head, pos, member);		\
+	     &pos->member != (head);					\
+	     pos = igt_list_next_entry(pos, member))
+
+#define igt_list_for_each_reverse(pos, head, member)			\
+	for (pos = igt_list_last_entry(head, pos, member);		\
+	     &pos->member != (head);					\
+	     pos = igt_list_prev_entry(pos, member))
+
+#define igt_list_for_each_safe(pos, tmp, head, member)			\
+	for (pos = igt_list_first_entry(head, pos, member),		\
+	     tmp = igt_list_next_entry(pos, member);			\
+	     &pos->member != (head);					\
+	     pos = tmp, tmp = igt_list_next_entry(pos, member))
+
+#endif /* IGT_LIST_H */
diff --git a/tests/drv_hangman.c b/tests/drv_hangman.c
index 1736d2a64..6ddae4912 100644
--- a/tests/drv_hangman.c
+++ b/tests/drv_hangman.c
@@ -199,9 +199,12 @@  static void test_error_state_capture(unsigned ring_id,
 
 	clear_error_state();
 
-	hang = igt_hang_ctx(device, 0, ring_id, HANG_ALLOW_CAPTURE, &offset);
-	batch = gem_mmap__cpu(device, hang.handle, 0, 4096, PROT_READ);
-	gem_set_domain(device, hang.handle, I915_GEM_DOMAIN_CPU, 0);
+	hang = igt_hang_ctx(device, 0, ring_id, HANG_ALLOW_CAPTURE);
+	offset = hang.spin->obj[1].offset;
+
+	batch = gem_mmap__cpu(device, hang.spin->handle, 0, 4096, PROT_READ);
+	gem_set_domain(device, hang.spin->handle, I915_GEM_DOMAIN_CPU, 0);
+
 	igt_post_hang_ring(device, hang);
 
 	check_error_state(ring_name, offset, batch);
diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c
index 3a1097ba5..4ac08c1b1 100644
--- a/tests/gem_concurrent_all.c
+++ b/tests/gem_concurrent_all.c
@@ -946,30 +946,19 @@  static igt_hang_t rcs_hang(void)
 
 static igt_hang_t all_hang(void)
 {
-	uint32_t bbe = MI_BATCH_BUFFER_END;
-	struct drm_i915_gem_execbuffer2 execbuf;
-	struct drm_i915_gem_exec_object2 obj;
-	igt_hang_t hang;
+	igt_hang_t hang = igt_hang_ring(fd, I915_EXEC_RENDER);
 	unsigned engine;
 
-	memset(&obj, 0, sizeof(obj));
-	obj.handle = gem_create(fd, 4096);
-	gem_write(fd, obj.handle, 0, &bbe, sizeof(&bbe));
-
-	memset(&execbuf, 0, sizeof(execbuf));
-	execbuf.buffers_ptr = to_user_pointer(&obj);
-	execbuf.buffer_count = 1;
-
 	for_each_physical_engine(fd, engine) {
-		hang = igt_hang_ring(fd, engine);
+		struct drm_i915_gem_execbuffer2 eb = hang.spin->execbuf;
 
-		execbuf.flags = engine;
-		__gem_execbuf(fd, &execbuf);
+		if (engine == I915_EXEC_RENDER)
+			continue;
 
-		gem_close(fd, hang.handle);
+		eb.flags = engine;
+		__gem_execbuf(fd, &eb);
 	}
 
-	hang.handle = obj.handle;
 	return hang;
 }
 
diff --git a/tests/gem_exec_schedule.c b/tests/gem_exec_schedule.c
index 35a44ab10..43ea97e61 100644
--- a/tests/gem_exec_schedule.c
+++ b/tests/gem_exec_schedule.c
@@ -423,7 +423,7 @@  static void preempt(int fd, unsigned ring, unsigned flags)
 	gem_context_set_priority(fd, ctx[HI], MAX_PRIO);
 
 	if (flags & HANG_LP)
-		hang = igt_hang_ctx(fd, ctx[LO], ring, 0, NULL);
+		hang = igt_hang_ctx(fd, ctx[LO], ring, 0);
 
 	for (int n = 0; n < ARRAY_SIZE(spin); n++) {
 		if (flags & NEW_CTX) {
@@ -730,7 +730,7 @@  static void preemptive_hang(int fd, unsigned ring)
 		gem_context_destroy(fd, ctx[LO]);
 	}
 
-	hang = igt_hang_ctx(fd, ctx[HI], ring, 0, NULL);
+	hang = igt_hang_ctx(fd, ctx[HI], ring, 0);
 	igt_post_hang_ring(fd, hang);
 
 	for (int n = 0; n < ARRAY_SIZE(spin); n++) {
diff --git a/tests/gem_mmap_gtt.c b/tests/gem_mmap_gtt.c
index fd60b8ff8..c8a0bedec 100644
--- a/tests/gem_mmap_gtt.c
+++ b/tests/gem_mmap_gtt.c
@@ -399,7 +399,7 @@  test_hang(int fd)
 
 		last_pattern = next_pattern;
 		next_pattern = (next_pattern + 1) % ARRAY_SIZE(patterns);
-	} while (gem_bo_busy(fd, hang.handle));
+	} while (gem_bo_busy(fd, hang.spin->handle));
 
 	igt_post_hang_ring(fd, hang);
 
diff --git a/tests/gem_reset_stats.c b/tests/gem_reset_stats.c
index 74ba2656a..ac9af23f2 100644
--- a/tests/gem_reset_stats.c
+++ b/tests/gem_reset_stats.c
@@ -164,7 +164,7 @@  static void inject_hang(int fd, uint32_t ctx,
 
 	clock_gettime(CLOCK_MONOTONIC, &ts_injected);
 
-	hang = igt_hang_ctx(fd, ctx, e->exec_id | e->flags, flags & BAN, NULL);
+	hang = igt_hang_ctx(fd, ctx, e->exec_id | e->flags, flags & BAN);
 	if ((flags & ASYNC) == 0)
 		igt_post_hang_ring(fd, hang);
 }
@@ -546,7 +546,7 @@  static void test_close_pending_fork(const struct intel_execution_engine *e,
 
 	assert_reset_status(fd, fd, 0, RS_NO_ERROR);
 
-	hang = igt_hang_ctx(fd, 0, e->exec_id | e->flags, 0, NULL);
+	hang = igt_hang_ctx(fd, 0, e->exec_id | e->flags, 0);
 	sleep(1);
 
 	/* Avoid helpers as we need to kill the child
diff --git a/tests/gem_shrink.c b/tests/gem_shrink.c
index 929e0426a..c8e05814e 100644
--- a/tests/gem_shrink.c
+++ b/tests/gem_shrink.c
@@ -208,7 +208,7 @@  static void hang(int fd, uint64_t alloc)
 		gem_execbuf(fd, &execbuf);
 	}
 
-	gem_close(fd, igt_hang_ring(fd, 0).handle);
+	gem_close(fd, igt_hang_ring(fd, 0).spin->handle);
 	for (int i = 0; i <= count; i++)
 		gem_madvise(fd, obj[i].handle, I915_MADV_DONTNEED);
 	munmap(obj, obj_size);
diff --git a/tests/gem_softpin.c b/tests/gem_softpin.c
index 23f936237..336008b8e 100644
--- a/tests/gem_softpin.c
+++ b/tests/gem_softpin.c
@@ -359,11 +359,12 @@  static void test_evict_hang(int fd)
 	execbuf.buffers_ptr = to_user_pointer(&object);
 	execbuf.buffer_count = 1;
 
-	hang = igt_hang_ctx(fd, 0, 0, 0, (uint64_t *)&expected);
-	object.offset = expected;
-	object.flags = EXEC_OBJECT_PINNED;
+	hang = igt_hang_ctx(fd, 0, 0, 0);
+	expected = hang.spin->obj[1].offset;
 
 	/* Replace the hung batch with ourselves, forcing an eviction */
+	object.offset = expected;
+	object.flags = EXEC_OBJECT_PINNED;
 	gem_execbuf(fd, &execbuf);
 	igt_assert_eq_u64(object.offset, expected);