summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-12-11 13:27:49 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-01-20 13:15:38 +0000
commit19642c604bb0c987e6e0069974042a98d128b9fc (patch)
treebfdbbce907b15f0efeb3658be597defe128efcb8
parent92caf138f2d878429f91397120e215dcb524efac (diff)
lib: Expand igt_hang_ring() to select target context and various options
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. v2: Disable the new kernel API, but push to provide a missing piece of infrastucture to unbreak compilation. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--lib/igt_gt.c92
-rw-r--r--lib/igt_gt.h12
-rw-r--r--lib/ioctl_wrappers.c14
-rw-r--r--lib/ioctl_wrappers.h1
4 files changed, 106 insertions, 13 deletions
diff --git a/lib/igt_gt.c b/lib/igt_gt.c
index 02ab68c3..84d764a9 100644
--- a/lib/igt_gt.c
+++ b/lib/igt_gt.c
@@ -38,6 +38,10 @@
#include "intel_reg.h"
#include "intel_chipset.h"
+#if NEW_CONTEXT_PARAM_NO_ERROR_CAPTURE_API
+#define LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4
+#endif
+
/**
* SECTION:igt_gt
* @short_description: GT support library
@@ -109,18 +113,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;
@@ -132,15 +143,34 @@ 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);
+
+ param.context = ctx;
param.size = 0;
+
+ if ((flags & HANG_ALLOW_CAPTURE) == 0) {
+#if NEW_CONTEXT_PARAM_NO_ERROR_CAPTURE_API
+ param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
+ param.value = 1;
+ /* Older kernels may not have NO_ERROR_CAPTURE, in which case
+ * we just eat the error state in post-hang (and hope we eat
+ * the right one).
+ */
+ __gem_context_set_param(fd, &param);
+#endif
+ }
+
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.param = LOCAL_CONTEXT_PARAM_BAN_PERIOD;
+ param.value = 0;
+ gem_context_set_param(fd, &param);
+ }
memset(&reloc, 0, sizeof(reloc));
memset(&exec, 0, sizeof(exec));
@@ -150,6 +180,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++;
@@ -166,9 +197,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);
}
/**
@@ -190,11 +251,22 @@ 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) {
+#if NEW_CONTEXT_PARAM_NO_ERROR_CAPTURE_API
+ param.param = LOCAL_CONTEXT_PARAM_NO_ERROR_CAPTURE;
+ param.value = 0;
+ if (__gem_context_set_param(fd, &param))
+ eat_error_state();
+#else
+ eat_error_state();
+#endif
+ }
}
/* GPU abusers */
diff --git a/lib/igt_gt.h b/lib/igt_gt.h
index 4f8eff50..3d81ec95 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 22c694b4..0024898f 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 fe2f687f..214ec788 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);