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>
This commit is contained in:
Chris Wilson 2015-12-11 13:27:49 +00:00
parent 92caf138f2
commit 19642c604b
4 changed files with 106 additions and 13 deletions

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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);