[Intel-gfx] [PATCH 4/4] igt/gem_evict_(alignment|everything): contend with GPU hangs
Chris Wilson
chris at chris-wilson.co.uk
Tue Oct 14 13:28:42 CEST 2014
Signed-off-by: Chris Wilson <chris at 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 b32297e..29625c4 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -52,6 +52,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"
@@ -130,6 +131,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 d74bb8c..67bd849 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
More information about the Intel-gfx
mailing list