From 6be2dc8ddfa332d129149aa3b13db14fa2cd6c0a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 19 Feb 2019 22:17:45 +0000 Subject: lib: Incrementally mlock() As we already have the previous portion of the mmap mlocked, we only need to mlock() the fresh portion for testing available memory. v2: Fixup the uint64_t pointer arithmetric and only use a single mmap to avoid subsequent mlock fail (for reasons unknown, but bet on mm/). Signed-off-by: Chris Wilson Cc: Caz Yokoyama Reviewed-by: Caz Yokoyama --- lib/igt_aux.h | 2 +- lib/intel_os.c | 40 ++++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'lib') diff --git a/lib/igt_aux.h b/lib/igt_aux.h index fb02c026..09b6246b 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -194,7 +194,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); +void *intel_get_total_pinnable_mem(size_t *pinned); 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 e1e31e23..dd93bea1 100644 --- a/lib/intel_os.c +++ b/lib/intel_os.c @@ -227,11 +227,9 @@ intel_get_total_swap_mb(void) * * Returns: Amount of memory that can be safely pinned, in bytes. */ -size_t -intel_get_total_pinnable_mem(void) +void *intel_get_total_pinnable_mem(size_t *total) { 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; @@ -245,34 +243,40 @@ intel_get_total_pinnable_mem(void) */ *can_mlock = (avail >> 1) + (avail >> 2); if (mlock(can_mlock, *can_mlock)) { - *can_mlock = 0; - goto out; + munmap(can_mlock, pin); + return MAP_FAILED; } 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); + uint64_t locked = *can_mlock; + + igt_debug("Testing mlock %'"PRIu64"B (%'"PRIu64"MiB) + %'"PRIu64"B\n", + locked, locked >> 20, inc); igt_fork(child, 1) { - for (uint64_t bytes = *can_mlock; - bytes <= pin; - bytes += inc) { - if (mlock(can_mlock, bytes)) + uint64_t bytes = *can_mlock; + + while (bytes <= pin) { + if (mlock((void *)can_mlock + bytes, inc)) break; - *can_mlock = bytes; + *can_mlock = bytes += inc; __sync_synchronize(); } } __igt_waitchildren(); - igt_assert(!mlock(can_mlock, *can_mlock)); - } -out: - ret = *can_mlock; - munmap(can_mlock, pin); + if (*can_mlock > locked + inc) { /* Weird bit of mm/ lore */ + *can_mlock -= inc; + igt_debug("Claiming mlock %'"PRIu64"B (%'"PRIu64"MiB)\n", + *can_mlock, *can_mlock >> 20); + igt_assert(!mlock((void *)can_mlock + locked, + *can_mlock - locked)); + } + } - return ret; + *total = pin; + return can_mlock; } static uint64_t vfs_file_max(void) -- cgit v1.2.3