mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-13 10:56:15 +00:00
kms_flip: Try to make hang_gpu() robust against hanging the GPU
On a bad day, hanging the GPU may be terminal. Yet even if the GPU is terminally wedged we expect modesetting (and pageflips) to continue. That deserves to be a dedicated test, but in the meantime we should strive to avoid falling over just because the code is not resilient. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
005d1dcc98
commit
3db29744f7
@ -658,42 +658,27 @@ static void set_y_tiling(struct test_output *o, int fb_idx)
|
|||||||
drmFree(r);
|
drmFree(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stop_rings(void)
|
||||||
static void exec_nop(int fd, uint32_t handle)
|
|
||||||
{
|
{
|
||||||
struct drm_i915_gem_execbuffer2 execbuf;
|
static const char dfs_base[] = "/sys/kernel/debug/dri";
|
||||||
struct drm_i915_gem_exec_object2 gem_exec[1];
|
static const char dfs_entry[] = "i915_ring_stop";
|
||||||
uint32_t b[2] = {MI_BATCH_BUFFER_END};
|
static const char data[] = "0xf";
|
||||||
|
char fname[FILENAME_MAX];
|
||||||
|
int card_index = drm_get_card();
|
||||||
|
int fd;
|
||||||
|
|
||||||
gem_write(fd, handle, 0, b, sizeof(b));
|
snprintf(fname, FILENAME_MAX, "%s/%i/%s",
|
||||||
|
dfs_base, card_index, dfs_entry);
|
||||||
|
|
||||||
gem_exec[0].handle = handle;
|
fd = open(fname, O_WRONLY);
|
||||||
gem_exec[0].relocation_count = 0;
|
igt_assert(fd >= 0);
|
||||||
gem_exec[0].relocs_ptr = 0;
|
|
||||||
gem_exec[0].alignment = 0;
|
|
||||||
gem_exec[0].offset = 0;
|
|
||||||
gem_exec[0].flags = 0;
|
|
||||||
gem_exec[0].rsvd1 = 0;
|
|
||||||
gem_exec[0].rsvd2 = 0;
|
|
||||||
|
|
||||||
execbuf.buffers_ptr = (uintptr_t)gem_exec;
|
igt_assert(write(fd, data, sizeof(data)) == sizeof(data));
|
||||||
execbuf.buffer_count = 1;
|
|
||||||
execbuf.batch_start_offset = 0;
|
|
||||||
execbuf.batch_len = 8;
|
|
||||||
execbuf.cliprects_ptr = 0;
|
|
||||||
execbuf.num_cliprects = 0;
|
|
||||||
execbuf.DR1 = 0;
|
|
||||||
execbuf.DR4 = 0;
|
|
||||||
execbuf.flags = I915_EXEC_RENDER;
|
|
||||||
i915_execbuffer2_set_context_id(execbuf, 0);
|
|
||||||
execbuf.rsvd2 = 0;
|
|
||||||
|
|
||||||
igt_assert(drmIoctl(fd,
|
close(fd);
|
||||||
DRM_IOCTL_I915_GEM_EXECBUFFER2,
|
|
||||||
&execbuf) == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eat_error_state(struct test_output *o)
|
static void eat_error_state(void)
|
||||||
{
|
{
|
||||||
static const char dfs_base[] = "/sys/kernel/debug/dri";
|
static const char dfs_base[] = "/sys/kernel/debug/dri";
|
||||||
static const char dfs_entry_error[] = "i915_error_state";
|
static const char dfs_entry_error[] = "i915_error_state";
|
||||||
@ -732,24 +717,36 @@ static void eat_error_state(struct test_output *o)
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hang_gpu(struct test_output *o)
|
static void unhang_gpu(int fd, uint32_t handle)
|
||||||
{
|
{
|
||||||
static const char dfs_base[] = "/sys/kernel/debug/dri";
|
gem_sync(drm_fd, handle);
|
||||||
static const char dfs_entry[] = "i915_ring_stop";
|
gem_close(drm_fd, handle);
|
||||||
static const char data[] = "0xf";
|
eat_error_state();
|
||||||
char fname[FILENAME_MAX];
|
}
|
||||||
int card_index = drm_get_card();
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
snprintf(fname, FILENAME_MAX, "%s/%i/%s",
|
static uint32_t hang_gpu(int fd)
|
||||||
dfs_base, card_index, dfs_entry);
|
{
|
||||||
|
struct drm_i915_gem_execbuffer2 execbuf;
|
||||||
|
struct drm_i915_gem_exec_object2 gem_exec;
|
||||||
|
uint32_t b[2] = {MI_BATCH_BUFFER_END};
|
||||||
|
|
||||||
fd = open(fname, O_WRONLY);
|
stop_rings();
|
||||||
igt_assert(fd >= 0);
|
|
||||||
|
|
||||||
igt_assert(write(fd, data, sizeof(data)) == sizeof(data));
|
memset(&gem_exec, 0, sizeof(gem_exec));
|
||||||
|
gem_exec.handle = gem_create(fd, 4096);
|
||||||
|
gem_write(fd, gem_exec.handle, 0, b, sizeof(b));
|
||||||
|
|
||||||
close(fd);
|
memset(&execbuf, 0, sizeof(execbuf));
|
||||||
|
execbuf.buffers_ptr = (uintptr_t)&gem_exec;
|
||||||
|
execbuf.buffer_count = 1;
|
||||||
|
execbuf.batch_len = sizeof(b);
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) {
|
||||||
|
unhang_gpu(fd, gem_exec.handle);
|
||||||
|
gem_exec.handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gem_exec.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_mode(struct test_output *o, uint32_t fb, int x, int y)
|
static int set_mode(struct test_output *o, uint32_t fb, int x, int y)
|
||||||
@ -786,7 +783,7 @@ static unsigned int run_test_step(struct test_output *o)
|
|||||||
bool do_vblank;
|
bool do_vblank;
|
||||||
struct vblank_reply vbl_reply;
|
struct vblank_reply vbl_reply;
|
||||||
unsigned int target_seq;
|
unsigned int target_seq;
|
||||||
uint32_t handle = 0; /* Suppress GCC warning */
|
uint32_t hang = 0; /* Suppress GCC warning */
|
||||||
|
|
||||||
target_seq = o->vblank_state.seq_step;
|
target_seq = o->vblank_state.seq_step;
|
||||||
/* Absolute waits only works once we have a frame counter. */
|
/* Absolute waits only works once we have a frame counter. */
|
||||||
@ -864,11 +861,8 @@ static unsigned int run_test_step(struct test_output *o)
|
|||||||
|
|
||||||
igt_info("."); fflush(stdout);
|
igt_info("."); fflush(stdout);
|
||||||
|
|
||||||
if (do_flip && (o->flags & TEST_HANG)) {
|
if (do_flip && (o->flags & TEST_HANG))
|
||||||
handle = gem_create(drm_fd, 4096);
|
hang = hang_gpu(drm_fd);
|
||||||
hang_gpu(o);
|
|
||||||
exec_nop(drm_fd, handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (do_flip)
|
if (do_flip)
|
||||||
do_or_die(do_page_flip(o, new_fb_id, !(o->flags & TEST_NOEVENT)));
|
do_or_die(do_page_flip(o, new_fb_id, !(o->flags & TEST_NOEVENT)));
|
||||||
@ -920,11 +914,8 @@ static unsigned int run_test_step(struct test_output *o)
|
|||||||
if (do_flip && (o->flags & TEST_EINVAL) && !(o->flags & TEST_FB_BAD_TILING))
|
if (do_flip && (o->flags & TEST_EINVAL) && !(o->flags & TEST_FB_BAD_TILING))
|
||||||
igt_assert(do_page_flip(o, new_fb_id, true) == expected_einval);
|
igt_assert(do_page_flip(o, new_fb_id, true) == expected_einval);
|
||||||
|
|
||||||
if (do_flip && (o->flags & TEST_HANG)) {
|
if (hang)
|
||||||
gem_sync(drm_fd, handle);
|
unhang_gpu(drm_fd, hang);
|
||||||
gem_close(drm_fd, handle);
|
|
||||||
eat_error_state(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
return completed_events;
|
return completed_events;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user