[igt-dev] [PATCH i-g-t v2 1/2] lib: Extract mlock probing

Michał Winiarski michal.winiarski at intel.com
Tue Jun 12 11:26:34 UTC 2018


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 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)

Signed-off-by: Michał Winiarski <michal.winiarski at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Ewelina Musial <ewelina.musial at intel.com>
---
 lib/igt_aux.h       |  1 +
 lib/intel_os.c      | 56 +++++++++++++++++++++++++++++++++++++++++++++
 tests/drv_suspend.c | 44 +++++++++--------------------------
 3 files changed, 68 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..8d096edf 100644
--- a/lib/intel_os.c
+++ b/lib/intel_os.c
@@ -183,6 +183,62 @@ 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;
+	size_t ret;
+
+	pin = (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 = (pin >> 1) + (pin >> 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
-- 
2.17.1



More information about the igt-dev mailing list