summaryrefslogtreecommitdiff
path: root/tests/i915/sysfs_heartbeat_interval.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2020-03-17 17:52:47 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2020-03-17 17:59:59 +0000
commitf698ffa1d958fcc87b596a78ff7b998faa7ea02d (patch)
tree89e72a86cfddb738ef3a0e3f6137b90a57e006c2 /tests/i915/sysfs_heartbeat_interval.c
parentdaebb89ae7906635e4b630febb0ffa1c05b0ee20 (diff)
i915/sysfs_heartbeat_interval: Use a measured sleep
Make sure our request durations are precise, as the scheduler tries hard to cause trouble. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Andi Shyti <andi.shyti@intel.com>
Diffstat (limited to 'tests/i915/sysfs_heartbeat_interval.c')
-rw-r--r--tests/i915/sysfs_heartbeat_interval.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/tests/i915/sysfs_heartbeat_interval.c b/tests/i915/sysfs_heartbeat_interval.c
index b7f440df..f13c72cb 100644
--- a/tests/i915/sysfs_heartbeat_interval.c
+++ b/tests/i915/sysfs_heartbeat_interval.c
@@ -265,6 +265,21 @@ static void test_nopreempt(int i915, int engine)
set_heartbeat(engine, saved);
}
+static unsigned int measured_usleep(unsigned int usec)
+{
+ struct timespec ts = { };
+ unsigned int slept;
+
+ slept = igt_nsec_elapsed(&ts);
+ igt_assert(slept == 0);
+ do {
+ usleep(usec - slept);
+ slept = igt_nsec_elapsed(&ts) / 1000;
+ } while (slept < usec);
+
+ return igt_nsec_elapsed(&ts);
+}
+
static void client(int i915, int engine, int *ctl, int duration, int expect)
{
unsigned int class, inst;
@@ -277,18 +292,29 @@ static void client(int i915, int engine, int *ctl, int duration, int expect)
ctx = create_context(i915, class, inst, 0);
while (!READ_ONCE(*ctl)) {
+ unsigned int elapsed;
igt_spin_t *spin;
spin = igt_spin_new(i915, ctx,
.flags = (IGT_SPIN_NO_PREEMPTION |
IGT_SPIN_POLL_RUN |
IGT_SPIN_FENCE_OUT));
+
igt_spin_busywait_until_started(spin);
+ igt_assert_eq(sync_fence_status(spin->out_fence), 0);
- igt_spin_set_timeout(spin, (uint64_t)duration * 1000 * 1000);
- sync_fence_wait(spin->out_fence, -1);
+ elapsed = measured_usleep(duration * 1000);
+ igt_spin_end(spin);
- igt_assert_eq(sync_fence_status(spin->out_fence), expect);
+ sync_fence_wait(spin->out_fence, -1);
+ if (sync_fence_status(spin->out_fence) != expect)
+ kill(getppid(), SIGALRM); /* cancel parent's sleep */
+
+ igt_assert_f(sync_fence_status(spin->out_fence) == expect,
+ "%s client: elapsed: %.3fms, expected %d, got %d\n",
+ expect < 0 ? "Bad" : "Good", elapsed * 1e-6,
+ expect, sync_fence_status(spin->out_fence));
+ igt_spin_free(i915, spin);
count++;
}
@@ -297,6 +323,10 @@ static void client(int i915, int engine, int *ctl, int duration, int expect)
expect < 0 ? "Bad" : "Good", count);
}
+static void sighandler(int sig)
+{
+}
+
static void __test_mixed(int i915, int engine,
int heartbeat,
int good,
@@ -304,6 +334,7 @@ static void __test_mixed(int i915, int engine,
int duration)
{
unsigned int saved;
+ sighandler_t old;
int *shared;
/*
@@ -325,7 +356,9 @@ static void __test_mixed(int i915, int engine,
igt_fork(child, 1) /* bad client */
client(i915, engine, shared, bad, -EIO);
+ old = signal(SIGALRM, sighandler);
sleep(duration);
+ signal(SIGALRM, old);
*shared = true;
igt_waitchildren();