[Intel-gfx] [PATCH igt 2/9] lib: Expand igt_hang_ring() to select target context and various options

Chris Wilson chris at chris-wilson.co.uk
Sat Dec 12 12:02:48 PST 2015


Some potential callers want to inject a hang into a particular context,
some want to trigger an actual ban and others may or may not want to
capture the associated error state. Expand the hang injection interface
to suit all.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 lib/igt_gt.c         | 82 +++++++++++++++++++++++++++++++++++++++++++++-------
 lib/igt_gt.h         | 12 ++++++++
 lib/ioctl_wrappers.c | 14 +++++++--
 lib/ioctl_wrappers.h |  1 +
 4 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 3d618d6..242bad1 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -37,6 +37,8 @@
 #include "intel_reg.h"
 #include "intel_chipset.h"
 
+#define LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
+
 /**
  * SECTION:igt_gt
  * @short_description: GT support library
@@ -84,18 +86,25 @@ void igt_require_hang_ring(int fd, int ring)
 }
 
 /**
- * igt_hang_ring:
+ * igt_hang_ring_ctx:
  * @fd: open i915 drm file descriptor
+ * @ctx: the contxt specifier
  * @ring: execbuf ring flag
+ * @flags: set of flags to control execution
  *
- * This helper function injects a hanging batch into @ring. It returns a
- * #igt_hang_ring_t structure which must be passed to igt_post_hang_ring() for
- * hang post-processing (after the gpu hang interaction has been tested.
+ * This helper function injects a hanging batch associated with @ctx into @ring.
+ * It returns a #igt_hang_ring_t structure which must be passed to
+ * igt_post_hang_ring() for hang post-processing (after the gpu hang
+ * interaction has been tested.
  *
  * Returns:
  * Structure with helper internal state for igt_post_hang_ring().
  */
-igt_hang_ring_t igt_hang_ring(int fd, int ring)
+igt_hang_ring_t igt_hang_ctx(int fd,
+			     uint32_t ctx,
+			     int ring,
+			     unsigned flags,
+			     uint64_t *offset)
 {
 	struct drm_i915_gem_relocation_entry reloc;
 	struct drm_i915_gem_execbuffer2 execbuf;
@@ -107,15 +116,28 @@ igt_hang_ring_t igt_hang_ring(int fd, int ring)
 
 	igt_require_hang_ring(fd, ring);
 
-	param.context = 0;
+	/* One day the kernel ABI will be fixed! */
+	igt_require(ctx == 0 || ring == I915_EXEC_RENDER);
+
+	if ((flags & HANG_ALLOW_CAPTURE) == 0) {
+		param.context = ctx;
+		param.size = 0;
+		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
+		param.value = 1;
+		__gem_context_set_param(fd, &param);
+	}
+
+	param.context = ctx;
 	param.size = 0;
 	param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD;
 	param.value = 0;
 	gem_context_get_param(fd, &param);
 	ban = param.value;
 
-	param.value = 0;
-	gem_context_set_param(fd, &param);
+	if ((flags & HANG_ALLOW_BAN) == 0) {
+		param.value = 0;
+		gem_context_set_param(fd, &param);
+	}
 
 	memset(&reloc, 0, sizeof(reloc));
 	memset(&exec, 0, sizeof(exec));
@@ -125,6 +147,7 @@ igt_hang_ring_t igt_hang_ring(int fd, int ring)
 	exec.relocation_count = 1;
 	exec.relocs_ptr = (uintptr_t)&reloc;
 
+	memset(b, 0xc5, sizeof(b));
 	len = 2;
 	if (intel_gen(intel_get_drm_devid(fd)) >= 8)
 		len++;
@@ -141,9 +164,39 @@ igt_hang_ring_t igt_hang_ring(int fd, int ring)
 	execbuf.buffer_count = 1;
 	execbuf.batch_len = sizeof(b);
 	execbuf.flags = ring;
+	i915_execbuffer2_set_context_id(execbuf, ctx);
 	gem_execbuf(fd, &execbuf);
 
-	return (struct igt_hang_ring){ exec.handle, ban };
+	if (offset)
+		*offset = exec.offset;
+
+	return (struct igt_hang_ring){ exec.handle, ctx, ban, flags };
+}
+
+/**
+ * igt_hang_ring:
+ * @fd: open i915 drm file descriptor
+ * @ring: execbuf ring flag
+ *
+ * This helper function injects a hanging batch into @ring. It returns a
+ * #igt_hang_ring_t structure which must be passed to igt_post_hang_ring() for
+ * hang post-processing (after the gpu hang interaction has been tested.
+ *
+ * Returns:
+ * Structure with helper internal state for igt_post_hang_ring().
+ */
+igt_hang_ring_t igt_hang_ring(int fd, int ring)
+{
+	return igt_hang_ctx(fd, 0, ring, 0, NULL);
+}
+
+static void eat_error_state(void)
+{
+	int fd;
+
+	fd = igt_debugfs_open("i915_error_state", O_WRONLY);
+	igt_assert(write(fd, "", 1) == 1);
+	close(fd);
 }
 
 /**
@@ -165,11 +218,20 @@ void igt_post_hang_ring(int fd, struct igt_hang_ring arg)
 		       I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
 	gem_close(fd, arg.handle);
 
-	param.context = 0;
+	param.context = arg.ctx;
 	param.size = 0;
 	param.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD;
 	param.value = arg.ban;
 	gem_context_set_param(fd, &param);
+
+	if ((arg.flags & HANG_ALLOW_CAPTURE) == 0) {
+		param.context = arg.ctx;
+		param.size = 0;
+		param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
+		param.value = 0;
+		if (__gem_context_set_param(fd, &param))
+			eat_error_state();
+	}
 }
 
 /* GPU abusers */
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index b70bbd1..4acf42b 100644
--- a/lib/igt_gt.h
+++ b/lib/igt_gt.h
@@ -30,9 +30,21 @@ void igt_require_hang_ring(int fd, int ring);
 
 typedef struct igt_hang_ring {
 	unsigned handle;
+	unsigned ctx;
 	unsigned ban;
+	unsigned flags;
 } igt_hang_ring_t;
 
+#define HANG_POISON 0xc5c5c5c5
+
+struct igt_hang_ring igt_hang_ctx(int fd,
+				  uint32_t ctx,
+				  int ring,
+				  unsigned flags,
+				  uint64_t *offset);
+#define HANG_ALLOW_BAN 1
+#define HANG_ALLOW_CAPTURE 2
+
 struct igt_hang_ring igt_hang_ring(int fd, int ring);
 void igt_post_hang_ring(int fd, struct igt_hang_ring arg);
 
diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
index e348f26..e1c0f28 100644
--- a/lib/ioctl_wrappers.c
+++ b/lib/ioctl_wrappers.c
@@ -816,6 +816,16 @@ void gem_context_get_param(int fd, struct local_i915_gem_context_param *p)
 	do_ioctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_GETPARAM, p);
 }
 
+int __gem_context_set_param(int fd, struct local_i915_gem_context_param *p)
+{
+#define LOCAL_I915_GEM_CONTEXT_SETPARAM       0x35
+#define LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_SETPARAM, struct local_i915_gem_context_param)
+	if (drmIoctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, p))
+		return -errno;
+
+	errno = 0;
+	return 0;
+}
 /**
  * gem_context_set_param:
  * @fd: open i915 drm file descriptor
@@ -828,9 +838,7 @@ void gem_context_get_param(int fd, struct local_i915_gem_context_param *p)
  */
 void gem_context_set_param(int fd, struct local_i915_gem_context_param *p)
 {
-#define LOCAL_I915_GEM_CONTEXT_SETPARAM       0x35
-#define LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + LOCAL_I915_GEM_CONTEXT_SETPARAM, struct local_i915_gem_context_param)
-	do_ioctl(fd, LOCAL_IOCTL_I915_GEM_CONTEXT_SETPARAM, p);
+	igt_assert(__gem_context_set_param(fd, p) == 0);
 }
 
 /**
diff --git a/lib/ioctl_wrappers.h b/lib/ioctl_wrappers.h
index fe2f687..214ec78 100644
--- a/lib/ioctl_wrappers.h
+++ b/lib/ioctl_wrappers.h
@@ -111,6 +111,7 @@ void gem_context_require_ban_period(int fd);
 void gem_context_require_param(int fd, uint64_t param);
 void gem_context_get_param(int fd, struct local_i915_gem_context_param *p);
 void gem_context_set_param(int fd, struct local_i915_gem_context_param *p);
+int __gem_context_set_param(int fd, struct local_i915_gem_context_param *p);
 
 void gem_sw_finish(int fd, uint32_t handle);
 
-- 
2.6.3



More information about the Intel-gfx mailing list