From 30e501adedf2c89839ef1d654a0281155cfbc589 Mon Sep 17 00:00:00 2001 From: Michał Winiarski Date: Mon, 11 Jun 2018 17:31:11 +0200 Subject: lib: Extract mlock probing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already have the routine we need in drv_suspend. Let's move it to lib and use it in the mlocking tests. We can also make it a bit faster if we tweak the initial step and initial amount. (I think it's safe to assume that we should be able to lock 3/4 of RAM, this cuts the probe time on my 32G SKL - from ~530s to ~180s) v2: Use available mem, amend step, also lock outside of fork, early exit if the assumption is wrong (Chris) Update the function name in doc (Ewelina) v3: Total for pin, available for initial lock (Chris) Signed-off-by: Michał Winiarski Cc: Chris Wilson Cc: Ewelina Musial Reviewed-by: Chris Wilson Reviewed-by: Ewelina Musial --- lib/igt_aux.h | 1 + lib/intel_os.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/drv_suspend.c | 44 +++++++++++------------------------------ 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 0eb96e44..9a962881 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -209,6 +209,7 @@ void intel_purge_vm_caches(int fd); uint64_t intel_get_avail_ram_mb(void); uint64_t intel_get_total_ram_mb(void); uint64_t intel_get_total_swap_mb(void); +size_t intel_get_total_pinnable_mem(void); int __intel_check_memory(uint64_t count, uint64_t size, unsigned mode, uint64_t *out_required, uint64_t *out_total); diff --git a/lib/intel_os.c b/lib/intel_os.c index f7ad05ac..e82173b3 100644 --- a/lib/intel_os.c +++ b/lib/intel_os.c @@ -183,6 +183,63 @@ intel_get_total_swap_mb(void) return retval / (1024*1024); } +/** + * intel_get_total_pinnable_mem: + * + * Compute the amount of memory that we're able to safely lock. + * Note that in order to achieve this, we're attempting to repeatedly lock more + * and more memory, which is a time consuming process. + * + * Returns: Amount of memory that can be safely pinned, in bytes. + */ +size_t +intel_get_total_pinnable_mem(void) +{ + uint64_t *can_mlock, pin, avail; + size_t ret; + + pin = (intel_get_total_ram_mb() + 1) << 20; + avail = (intel_get_avail_ram_mb() + 1) << 20; + + can_mlock = mmap(NULL, pin, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + igt_require(can_mlock != MAP_FAILED); + + /* + * We can reasonably assume that we should be able to lock at + * least 3/4 of available RAM + */ + *can_mlock = (avail >> 1) + (avail >> 2); + if (mlock(can_mlock, *can_mlock)) { + *can_mlock = 0; + goto out; + } + + for (uint64_t inc = 1024 << 20; inc >= 4 << 10; inc >>= 2) { + igt_debug("Testing mlock %'"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(); + igt_assert(!mlock(can_mlock, *can_mlock)); + } + +out: + ret = *can_mlock; + munmap(can_mlock, pin); + + return ret; +} + static uint64_t vfs_file_max(void) { static long long unsigned max; diff --git a/tests/drv_suspend.c b/tests/drv_suspend.c index 9a9ff200..b4212dca 100644 --- a/tests/drv_suspend.c +++ b/tests/drv_suspend.c @@ -163,52 +163,30 @@ test_sysfs_reader(bool hibernate) static void test_shrink(int fd, unsigned int mode) { - uint64_t *can_mlock, pin; + void *mem; + size_t size; 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(); - } + size = intel_get_total_pinnable_mem(); + igt_require(size > 64 << 20); + size -= 64 << 20; - intel_purge_vm_caches(fd); + mem = mmap(NULL, size, PROT_READ, MAP_SHARED | MAP_ANON, -1, 0); - igt_require(*can_mlock > 64 << 20); - *can_mlock -= 64 << 20; + intel_purge_vm_caches(fd); igt_debug("Locking %'"PRIu64" B (%'"PRIu64" MiB)\n", - *can_mlock, *can_mlock >> 20); - igt_assert(!mlock(can_mlock, *can_mlock)); + size, size >> 20); + igt_assert(!mlock(mem, size)); igt_info("Locked %'"PRIu64" B (%'"PRIu64" MiB)\n", - *can_mlock, *can_mlock >> 20); + size, size >> 20); intel_purge_vm_caches(fd); igt_system_suspend_autoresume(mode, SUSPEND_TEST_NONE); - munmap(can_mlock, pin); + munmap(mem, size); } static void -- cgit v1.2.3