From e8eb9afd4c53e67d834f520a42a641adb874a463 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Mar 2017 13:09:00 +0000 Subject: igt: Exercise the shrinker Introduce a new fork helper that spawns a process that just repeatedly calls i915_gem_shrink_all() and watch what happens as we try to use objects that have been shrunk. Signed-off-by: Chris Wilson --- lib/igt_aux.c | 39 +++++++++++++++++++++++++++++++++++++++ lib/igt_aux.h | 3 +++ lib/igt_debugfs.c | 22 ++++++++++++++++++++++ lib/igt_debugfs.h | 9 +++++++++ tests/gem_concurrent_all.c | 15 +++++++++++++++ tests/gem_render_linear_blits.c | 12 +++++++++++- tests/gem_render_tiled_blits.c | 12 +++++++++++- 7 files changed, 110 insertions(+), 2 deletions(-) diff --git a/lib/igt_aux.c b/lib/igt_aux.c index 5117dbec..7ee279a3 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -349,6 +349,45 @@ void igt_stop_signal_helper(void) sig_stat = 0; } +static struct igt_helper_process shrink_helper; +static void __attribute__((noreturn)) shrink_helper_process(pid_t pid) +{ + while (1) { + igt_drop_caches_set(DROP_SHRINK_ALL); + usleep(1000 * 1000 / 50); + if (kill(pid, 0)) /* Parent has died, so must we. */ + exit(0); + } +} + +/** + * igt_fork_shrink_helper: + * + * Fork a child process using #igt_fork_helper to force all available objects + * to be paged out (via i915_gem_shrink()). + * + * This is useful to exercise swapping paths, without requiring us to hit swap. + * + * This should only be used from an igt_fixture. + */ +void igt_fork_shrink_helper(void) +{ + assert(!igt_only_list_subtests()); + igt_require(igt_drop_caches_has(DROP_SHRINK_ALL)); + igt_fork_helper(&shrink_helper) + shrink_helper_process(getppid()); +} + +/** + * igt_stop_shrink_helper: + * + * Stops the child process spawned with igt_fork_shrink_helper(). + */ +void igt_stop_shrink_helper(void) +{ + igt_stop_helper(&shrink_helper); +} + #if HAVE_UDEV #include diff --git a/lib/igt_aux.h b/lib/igt_aux.h index cb54ca5e..13f6f156 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -51,6 +51,9 @@ extern int num_trash_bos; void igt_fork_signal_helper(void); void igt_stop_signal_helper(void); +void igt_fork_shrink_helper(void); +void igt_stop_shrink_helper(void); + void igt_fork_hang_detector(int fd); void igt_stop_hang_detector(void); diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c index e64d001b..0a991a1f 100644 --- a/lib/igt_debugfs.c +++ b/lib/igt_debugfs.c @@ -872,6 +872,28 @@ void igt_pipe_crc_collect_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out_crc) * Drop caches */ +/** + * igt_drop_caches_has: + * @val: bitmask for DROP_* values + * + * This queries the debugfs to see if it supports the full set of desired + * operations. + */ +bool igt_drop_caches_has(uint64_t val) +{ + FILE *file; + uint64_t mask; + + mask = 0; + file = igt_debugfs_fopen("i915_gem_drop_caches", "r"); + if (file) { + fscanf(file, "0x%" PRIx64, &mask); + fclose(file); + } + + return (val & mask) == val; +} + /** * igt_drop_caches_set: * @val: bitmask for DROP_* values diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h index 5587ad40..aa59f8a8 100644 --- a/lib/igt_debugfs.h +++ b/lib/igt_debugfs.h @@ -169,6 +169,13 @@ void igt_require_hpd_storm_ctl(void); * Also drop freed objects. */ #define DROP_FREED 0x10 +/** + * DROP_SHRINK_ALL: + * + * Force all unpinned buffers to be evicted from their GTT and returned to the + * system. + */ +#define DROP_SHRINK_ALL 0x20 /** * DROP_ALL: * @@ -176,10 +183,12 @@ void igt_require_hpd_storm_ctl(void); */ #define DROP_ALL (DROP_UNBOUND | \ DROP_BOUND | \ + DROP_SHRINK_ALL | \ DROP_RETIRE | \ DROP_ACTIVE | \ DROP_FREED) +bool igt_drop_caches_has(uint64_t val); void igt_drop_caches_set(uint64_t val); /* diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c index 6ec461d3..aecd5e28 100644 --- a/tests/gem_concurrent_all.c +++ b/tests/gem_concurrent_all.c @@ -1898,6 +1898,21 @@ igt_main run_modes(name, c, modes, s, count); } + snprintf(name, sizeof(name), "%s%s-%s", + c->name, s->name, "shrink"); + igt_subtest_group { + igt_fixture { + count = num_buffers(gem_mappable_aperture_size(), + s, c, CHECK_RAM); + + igt_fork_shrink_helper(); + } + run_modes(name, c, modes, s, count); + + igt_fixture + igt_stop_shrink_helper(); + } + /* Use the entire mappable aperture, force swapping */ snprintf(name, sizeof(name), "%s%s-%s", c->name, s->name, "swap"); diff --git a/tests/gem_render_linear_blits.c b/tests/gem_render_linear_blits.c index 13f76a56..acc3bd5a 100644 --- a/tests/gem_render_linear_blits.c +++ b/tests/gem_render_linear_blits.c @@ -197,12 +197,22 @@ igt_main /* the rest of the tests are too long for simulation */ igt_skip_on_simulation(); - igt_subtest("apperture-thrash") { + igt_subtest("aperture-thrash") { count = 3 * gem_aperture_size(fd) / SIZE / 2; intel_require_memory(count, SIZE, CHECK_RAM); run_test(fd, count); } + igt_subtest("aperture-shrink") { + igt_fork_shrink_helper(); + + count = 3 * gem_aperture_size(fd) / SIZE / 2; + intel_require_memory(count, SIZE, CHECK_RAM); + run_test(fd, count); + + igt_stop_shrink_helper(); + } + igt_subtest("swap-thrash") { uint64_t swap_mb = intel_get_total_swap_mb(); igt_require(swap_mb > 0); diff --git a/tests/gem_render_tiled_blits.c b/tests/gem_render_tiled_blits.c index 9f0e5884..aebbcb96 100644 --- a/tests/gem_render_tiled_blits.c +++ b/tests/gem_render_tiled_blits.c @@ -210,12 +210,22 @@ igt_main /* the rest of the tests are too long for simulation */ igt_skip_on_simulation(); - igt_subtest("apperture-thrash") { + igt_subtest("aperture-thrash") { count = 3 * gem_aperture_size(fd) / SIZE / 2; intel_require_memory(count, SIZE, CHECK_RAM); run_test(fd, count); } + igt_subtest("aperture-shrink") { + igt_fork_shrink_helper(); + + count = 3 * gem_aperture_size(fd) / SIZE / 2; + intel_require_memory(count, SIZE, CHECK_RAM); + run_test(fd, count); + + igt_stop_shrink_helper(); + } + igt_subtest("swap-thrash") { uint64_t swap_mb = intel_get_total_swap_mb(); igt_require(swap_mb > 0); -- cgit v1.2.3