summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Winiarski <michal.winiarski@intel.com>2018-06-11 17:31:11 +0200
committerMichał Winiarski <michal.winiarski@intel.com>2018-06-13 12:43:23 +0200
commit30e501adedf2c89839ef1d654a0281155cfbc589 (patch)
tree7b44e7da62f132e5c4106a7569e77798df849803
parente94ce40798e35d2e3c4494f50b617908066bbf8b (diff)
lib: Extract mlock probing
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 <michal.winiarski@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Ewelina Musial <ewelina.musial@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Ewelina Musial <ewelina.musial@intel.com>
-rw-r--r--lib/igt_aux.h1
-rw-r--r--lib/intel_os.c57
-rw-r--r--tests/drv_suspend.c44
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