diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-18 09:04:07 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-03-18 09:20:06 +0000 |
commit | dcb39b5270b5ff4d91a595ae05c9e74528bce546 (patch) | |
tree | b143137cbd6bd756d5d4fbf5656ef65a42faf101 | |
parent | 34098b71fa1b365ffb0c12fb84ebb7aa26c8f300 (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.c | 17 | ||||
-rw-r--r-- | lib/igt_core.h | 35 | ||||
-rw-r--r-- | tests/gem_softpin.c | 52 |
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); } |