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 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) (limited to 'lib') 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; -- cgit v1.2.3