diff options
-rw-r--r-- | lib/igt_core.c | 34 | ||||
-rw-r--r-- | lib/igt_core.h | 1 | ||||
-rw-r--r-- | tests/drv_suspend.c | 54 |
3 files changed, 75 insertions, 14 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c index 5092a3f0..06d8b037 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -1702,20 +1702,7 @@ void igt_child_done(pid_t pid) test_children[i] = test_children[i + 1]; } -/** - * igt_waitchildren: - * - * Wait for all children forked with igt_fork. - * - * The magic here is that exit codes from children will be correctly propagated - * to the main thread, including the relevant exit code if a child thread failed. - * Of course if multiple children failed with different exit codes the resulting - * exit code will be non-deterministic. - * - * Note that igt_skip() will not be forwarded, feature tests need to be done - * before spawning threads with igt_fork(). - */ -void igt_waitchildren(void) +int __igt_waitchildren(void) { int err = 0; int count; @@ -1761,6 +1748,25 @@ void igt_waitchildren(void) } num_test_children = 0; + return err; +} + +/** + * igt_waitchildren: + * + * Wait for all children forked with igt_fork. + * + * The magic here is that exit codes from children will be correctly propagated + * to the main thread, including the relevant exit code if a child thread failed. + * Of course if multiple children failed with different exit codes the resulting + * exit code will be non-deterministic. + * + * Note that igt_skip() will not be forwarded, feature tests need to be done + * before spawning threads with igt_fork(). + */ +void igt_waitchildren(void) +{ + int err = __igt_waitchildren(); if (err) igt_fail(err); } diff --git a/lib/igt_core.h b/lib/igt_core.h index bf8cd66c..a73b0649 100644 --- a/lib/igt_core.h +++ b/lib/igt_core.h @@ -742,6 +742,7 @@ bool __igt_fork(void); for (int child = 0; child < (num_children); child++) \ for (; __igt_fork(); exit(0)) void igt_child_done(pid_t pid); +int __igt_waitchildren(void); void igt_waitchildren(void); void igt_waitchildren_timeout(int seconds, const char *reason); diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c index 2e39f20a..9a9ff200 100644 --- a/tests/drv_suspend.c +++ b/tests/drv_suspend.c @@ -161,6 +161,57 @@ test_sysfs_reader(bool hibernate) } static void +test_shrink(int fd, unsigned int mode) +{ + uint64_t *can_mlock, pin; + + gem_quiescent_gpu(fd); + intel_purge_vm_caches(fd); + + pin = (intel_get_total_ram_mb() + 1) << 20; + + igt_debug("Total memory %'"PRIu64" B (%'"PRIu64" MiB)\n", + pin, pin >> 20); + can_mlock = mmap(NULL, pin, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + igt_require(can_mlock != MAP_FAILED); + + /* Lock all the system memory, forcing the driver into swap and OOM */ + for (uint64_t inc = 64 << 20; inc >= 4 << 10; inc >>= 1) { + igt_debug("Testing+ %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + + igt_fork(child, 1) { + for (uint64_t bytes = *can_mlock; + bytes <= pin; + bytes += inc) { + if (mlock(can_mlock, bytes)) + break; + + *can_mlock = bytes; + __sync_synchronize(); + } + } + __igt_waitchildren(); + } + + intel_purge_vm_caches(fd); + + igt_require(*can_mlock > 64 << 20); + *can_mlock -= 64 << 20; + + igt_debug("Locking %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + igt_assert(!mlock(can_mlock, *can_mlock)); + igt_info("Locked %'"PRIu64" B (%'"PRIu64" MiB)\n", + *can_mlock, *can_mlock >> 20); + + intel_purge_vm_caches(fd); + igt_system_suspend_autoresume(mode, SUSPEND_TEST_NONE); + + munmap(can_mlock, pin); +} + +static void test_forcewake(int fd, bool hibernate) { int fw_fd; @@ -199,6 +250,9 @@ igt_main igt_subtest("sysfs-reader") test_sysfs_reader(false); + igt_subtest("shrink") + test_shrink(fd, SUSPEND_STATE_MEM); + igt_subtest("forcewake") test_forcewake(fd, false); |