Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- lib/igt_aux.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ lib/igt_aux.h | 4 +++ tests/gem_evict_alignment.c | 15 ++++++++++ tests/gem_evict_everything.c | 15 ++++++++++ 4 files changed, 103 insertions(+) diff --git a/lib/igt_aux.c b/lib/igt_aux.c index 0e1eeea..b78ca2f 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -53,6 +53,7 @@ #include "intel_chipset.h" #include "igt_aux.h" #include "igt_debugfs.h" +#include "igt_gt.h" #include "config.h" #include "intel_reg.h" #include "ioctl_wrappers.h" @@ -131,6 +132,74 @@ void igt_stop_signal_helper(void) sig_stat = 0; } +/* GPU abusers */ +static struct igt_helper_process hang_helper; +static void __attribute__((noreturn)) +hang_helper_process(pid_t pid, int fd, int gen) +{ + while (1) { + if (kill(pid, 0)) /* Parent has died, so must we. */ + exit(0); + + igt_post_hang_ring(fd, + igt_hang_ring(fd, gen, I915_EXEC_DEFAULT)); + + sleep(1); + } +} + +/** + * igt_fork_hang_helper: + * + * Fork a child process using #igt_fork_helper to hang the default engine + * of the GPU at regular intervals. + * + * This is useful to exercise slow running code (such as aperture placement) + * which needs to be robust against a GPU reset. + * + * In tests with subtests this function can be called outside of failure + * catching code blocks like #igt_fixture or #igt_subtest. + */ +int igt_fork_hang_helper(void) +{ + int fd, gen; + + if (igt_only_list_subtests()) + return 1; + + fd = drm_open_any(); + if (fd == -1) + return 0; + + gen = intel_gen(intel_get_drm_devid(fd)); + if (gen < 5) { + close(fd); + return 0; + } + + igt_fork_helper(&hang_helper) + hang_helper_process(getppid(), fd, gen); + + close(fd); + return 1; +} + +/** + * igt_stop_hang_helper: + * + * Stops the child process spawned with igt_fork_hang_helper(). + * + * In tests with subtests this function can be called outside of failure + * catching code blocks like #igt_fixture or #igt_subtest. + */ +void igt_stop_hang_helper(void) +{ + if (igt_only_list_subtests()) + return; + + igt_stop_helper(&hang_helper); +} + /** * igt_check_boolean_env_var: * @env_var: environment variable name diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 9b42918..6056575 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -35,6 +35,10 @@ /* generally useful helpers */ void igt_fork_signal_helper(void); void igt_stop_signal_helper(void); + +int igt_fork_hang_helper(void); +void igt_stop_hang_helper(void); + void igt_exchange_int(void *array, unsigned i, unsigned j); void igt_permute_array(void *array, unsigned size, void (*exchange_func)(void *array, diff --git a/tests/gem_evict_alignment.c b/tests/gem_evict_alignment.c index e814f36..3ee23b9 100644 --- a/tests/gem_evict_alignment.c +++ b/tests/gem_evict_alignment.c @@ -221,6 +221,21 @@ igt_main count = 4; major_evictions(fd, size, count); } + + if (igt_fork_hang_helper()) { + igt_subtest("minor-hang") { + size = 1024 * 1024; + count = 3*gem_aperture_size(fd) / size / 4; + minor_evictions(fd, size, count); + } + + igt_subtest("major-hang") { + size = 3*gem_aperture_size(fd) / 4; + count = 4; + major_evictions(fd, size, count); + } + igt_stop_hang_helper(); + } igt_stop_signal_helper(); igt_fixture diff --git a/tests/gem_evict_everything.c b/tests/gem_evict_everything.c index c1eb3bd..596891c 100644 --- a/tests/gem_evict_everything.c +++ b/tests/gem_evict_everything.c @@ -234,6 +234,21 @@ igt_main test_major_evictions(fd, size, count); } + if (igt_fork_hang_helper()) { + igt_subtest("swapping-hang") + test_swapping_evictions(fd, size, count); + + igt_subtest("minor-hang") + test_minor_evictions(fd, size, count); + + igt_subtest("major-hang") { + size = 3*gem_aperture_size(fd) / 4; + count = 4; + test_major_evictions(fd, size, count); + } + + igt_stop_hang_helper(); + } igt_stop_signal_helper(); igt_fixture { -- 2.1.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx