Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
---
 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@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to