summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-03-18 09:04:07 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2016-03-18 09:20:06 +0000
commitdcb39b5270b5ff4d91a595ae05c9e74528bce546 (patch)
treeb143137cbd6bd756d5d4fbf5656ef65a42faf101
parent34098b71fa1b365ffb0c12fb84ebb7aa26c8f300 (diff)
igt/gem_softpin: Repeat tests with signal interruptions
For the long running tests probing error conditions, throwing in the signal interruptions is a good idea. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--lib/igt_core.c17
-rw-r--r--lib/igt_core.h35
-rw-r--r--tests/gem_softpin.c52
3 files changed, 90 insertions, 14 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c
index 4ade5491..3c092a5f 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -396,6 +396,23 @@ error:
return -errno;
}
+#define MSEC_PER_SEC (1000)
+#define USEC_PER_SEC (1000*MSEC_PER_SEC)
+#define NSEC_PER_SEC (1000*USEC_PER_SEC)
+uint64_t igt_nsec_elapsed(struct timespec *start)
+{
+ struct timespec now;
+
+ gettime(&now);
+ if ((start->tv_sec | start->tv_nsec) == 0) {
+ *start = now;
+ return 0;
+ }
+
+ return ((now.tv_nsec - start->tv_nsec) +
+ NSEC_PER_SEC*(now.tv_sec - start->tv_sec));
+}
+
bool __igt_fixture(void)
{
assert(!in_fixture);
diff --git a/lib/igt_core.h b/lib/igt_core.h
index 9314ae94..124ae0d9 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -32,6 +32,7 @@
#include <setjmp.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -775,6 +776,40 @@ extern enum igt_log_level igt_log_level;
void igt_set_timeout(unsigned int seconds,
const char *op);
+/**
+ * igt_nsec_elapsed:
+ * @start: measure from this point in time
+ *
+ * Reports the difference in the monotonic clock from the start time
+ * in nanoseconds. On the first invocation, start should be zeroed and will
+ * be set by the call.
+ *
+ * Typical use would be:
+ *
+ * igt_subtest("test") {
+ * struct timespec start = {};
+ * while (igt_nsec_elapsed(&start) < test_timeout_ns)
+ * do_test();
+ * }
+ *
+ * A handy approximation is to use nsec >> 30 to convert to seconds,
+ * nsec >> 20 to convert to milliseconds - the error is about 8%, acceptable
+ * for test run times.
+ */
+uint64_t igt_nsec_elapsed(struct timespec *start);
+
+/**
+ * igt_seconds_elapsed:
+ * @start: measure from this point in time
+ *
+ * A wrapper around igt_nsec_elapsed that reports the approximate (8% error)
+ * number of seconds since the start point.
+ */
+static inline uint32_t igt_seconds_elapsed(struct timespec *start)
+{
+ return igt_nsec_elapsed(start) >> 30;
+}
+
void igt_reset_timeout(void);
FILE *__igt_fopen_data(const char* igt_srcdir, const char* igt_datadir,
diff --git a/tests/gem_softpin.c b/tests/gem_softpin.c
index eb5ede60..62d22cee 100644
--- a/tests/gem_softpin.c
+++ b/tests/gem_softpin.c
@@ -271,19 +271,19 @@ static void test_evict_active(int fd)
object.handle = gem_create(fd, 4096);
gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
+ memset(&execbuf, 0, sizeof(execbuf));
+ execbuf.buffers_ptr = (uintptr_t)&object;
+ execbuf.buffer_count = 1;
+
expected = busy_batch(fd);
object.offset = expected;
object.flags = EXEC_OBJECT_PINNED;
/* Replace the active batch with ourselves, forcing an eviction */
- memset(&execbuf, 0, sizeof(execbuf));
- execbuf.buffers_ptr = (uintptr_t)&object;
- execbuf.buffer_count = 1;
-
gem_execbuf(fd, &execbuf);
- gem_close(fd, object.handle);
-
igt_assert_eq_u64(object.offset, expected);
+
+ gem_close(fd, object.handle);
}
static void test_evict_snoop(int fd)
@@ -348,28 +348,27 @@ static void test_evict_hang(int fd)
const uint32_t bbe = MI_BATCH_BUFFER_END;
struct drm_i915_gem_execbuffer2 execbuf;
struct drm_i915_gem_exec_object2 object;
- uint64_t expected;
igt_hang_ring_t hang;
+ uint64_t expected;
memset(&object, 0, sizeof(object));
object.handle = gem_create(fd, 4096);
gem_write(fd, object.handle, 0, &bbe, sizeof(bbe));
- hang = igt_hang_ctx(fd, 0, 0, 0, (uint64_t *)&expected);
- object.offset = expected;
- object.flags = EXEC_OBJECT_PINNED;
-
- /* Replace the hanging batch with ourselves, forcing an eviction */
memset(&execbuf, 0, sizeof(execbuf));
execbuf.buffers_ptr = (uintptr_t)&object;
execbuf.buffer_count = 1;
- gem_execbuf(fd, &execbuf);
- gem_close(fd, object.handle);
+ hang = igt_hang_ctx(fd, 0, 0, 0, (uint64_t *)&expected);
+ object.offset = expected;
+ object.flags = EXEC_OBJECT_PINNED;
+ /* Replace the hung batch with ourselves, forcing an eviction */
+ gem_execbuf(fd, &execbuf);
igt_assert_eq_u64(object.offset, expected);
igt_post_hang_ring(fd, hang);
+ gem_close(fd, object.handle);
}
static void xchg_offset(void *array, unsigned i, unsigned j)
@@ -489,12 +488,14 @@ igt_main
test_softpin(fd);
igt_subtest("overlap")
test_overlap(fd);
+
igt_subtest("noreloc")
test_noreloc(fd, NOSLEEP);
igt_subtest("noreloc-S3")
test_noreloc(fd, SUSPEND);
igt_subtest("noreloc-S4")
test_noreloc(fd, HIBERNATE);
+
igt_subtest("evict-active")
test_evict_active(fd);
igt_subtest("evict-snoop")
@@ -502,6 +503,29 @@ igt_main
igt_subtest("evict-hang")
test_evict_hang(fd);
+ igt_fork_signal_helper();
+ igt_subtest("noreloc-interruptible") {
+ struct timespec start = {};
+ while (igt_seconds_elapsed(&start) < 20)
+ test_noreloc(fd, NOSLEEP);
+ }
+ igt_subtest("evict-active-interruptible") {
+ struct timespec start = {};
+ while (igt_seconds_elapsed(&start) < 20)
+ test_evict_active(fd);
+ }
+ igt_subtest("evict-snoop-interruptible") {
+ struct timespec start = {};
+ while (igt_seconds_elapsed(&start) < 20)
+ test_evict_snoop(fd);
+ }
+ igt_subtest("evict-hang-interruptible") {
+ struct timespec start = {};
+ while (igt_seconds_elapsed(&start) < 20)
+ test_evict_hang(fd);
+ }
+ igt_stop_signal_helper();
+
igt_fixture
close(fd);
}