Blame SOURCES/0027-tests-Improve-TASK_SIZE-detection-in-task-size-overr.patch

fc9b0e
From 96efdf51429812ec9b09f5ddb6ff24c80719e628 Mon Sep 17 00:00:00 2001
fc9b0e
Message-Id: <96efdf51429812ec9b09f5ddb6ff24c80719e628.1566225007.git.aquini@redhat.com>
fc9b0e
In-Reply-To: <d42f467a923dfc09309acb7a83b42e3285fbd8f4.1566225007.git.aquini@redhat.com>
fc9b0e
References: <d42f467a923dfc09309acb7a83b42e3285fbd8f4.1566225007.git.aquini@redhat.com>
fc9b0e
From: David Gibson <david@gibson.dropbear.id.au>
fc9b0e
Date: Sun, 18 Aug 2019 16:03:21 +1000
fc9b0e
Subject: [RHEL7 PATCH 27/31] tests: Improve TASK_SIZE detection in
fc9b0e
 task-size-overrun
fc9b0e
fc9b0e
task-size-overrun is designed to test kernel behaviour in some edge cases
fc9b0e
involving making a hugepage mapping right near the address space limits.
fc9b0e
In order to do that, it needs to know the TASK_SIZE of the kernel it's
fc9b0e
running on.
fc9b0e
fc9b0e
Currently it does that with a linear search from the last extant mapping.
fc9b0e
But with kernels supporting a very large address space that can take
fc9b0e
prohibitively long.  We've had problems with that before, resulting in some
fc9b0e
hacks to skip a large chunk of address space.
fc9b0e
fc9b0e
Those hacks are dependent on platform, though, which is ugly and fragile.
fc9b0e
Case in point, recent powerpc kernels now support a 4PiB address space,
fc9b0e
so the logic we have there is insufficient to finish the search in
fc9b0e
reasonable time.
fc9b0e
fc9b0e
To handle this in a more robust way, this replaces the linear search with
fc9b0e
a binary search between the last extant mapping and (2^wordsize).
fc9b0e
fc9b0e
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
fc9b0e
Signed-off-by: Eric B Munson <eric@munsonfam.org>
fc9b0e
Signed-off-by: Rafael Aquini <aquini@redhat.com>
fc9b0e
---
fc9b0e
 tests/task-size-overrun.c | 57 +++++++++++++++++++++++------------------------
fc9b0e
 1 file changed, 28 insertions(+), 29 deletions(-)
fc9b0e
fc9b0e
diff --git a/tests/task-size-overrun.c b/tests/task-size-overrun.c
fc9b0e
index 914ef65..29b6045 100644
fc9b0e
--- a/tests/task-size-overrun.c
fc9b0e
+++ b/tests/task-size-overrun.c
fc9b0e
@@ -64,45 +64,44 @@ static unsigned long find_last_mapped(void)
fc9b0e
 	return end;
fc9b0e
 }
fc9b0e
 
fc9b0e
+#define ALIGN_DOWN(x,a) ((x) & ~((a) - 1))
fc9b0e
+
fc9b0e
 static unsigned long find_task_size(void)
fc9b0e
 {
fc9b0e
-	unsigned long addr;
fc9b0e
+	unsigned long low, high; /* PFNs */
fc9b0e
 	void *p;
fc9b0e
 
fc9b0e
-	addr = find_last_mapped();
fc9b0e
-	if (!addr || ((addr % getpagesize()) != 0))
fc9b0e
-		FAIL("Bogus stack end address, 0x%lx!?", addr);
fc9b0e
+	low = find_last_mapped();
fc9b0e
+	if (!low || ((low % getpagesize()) != 0))
fc9b0e
+		FAIL("Bogus stack end address, 0x%lx!?", low);
fc9b0e
+	low = low / getpagesize();
fc9b0e
+
fc9b0e
+	/* This sum should get us (2^(wordsize) - 2 pages) */
fc9b0e
+	high = (unsigned long)(-2 * getpagesize()) / getpagesize();
fc9b0e
+
fc9b0e
+	verbose_printf("Binary searching for task size PFNs 0x%lx..0x%lx\n",
fc9b0e
+		       low, high);
fc9b0e
+
fc9b0e
+	while (high > low + 1) {
fc9b0e
+		unsigned long pfn = (low + high) / 2;
fc9b0e
+		unsigned long addr = pfn * getpagesize();
fc9b0e
+
fc9b0e
+		assert((pfn >= low) && (pfn <= high));
fc9b0e
 
fc9b0e
-	while (addr) {
fc9b0e
 		p = mmap64((void *)addr, getpagesize(), PROT_READ,
fc9b0e
 			   MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
fc9b0e
 		if (p == MAP_FAILED) {
fc9b0e
-			verbose_printf("Searching map failed: %s\n", strerror(errno));
fc9b0e
-			return addr;
fc9b0e
+			verbose_printf("Map failed at 0x%lx (%s)\n",
fc9b0e
+				       addr, strerror(errno));
fc9b0e
+			high = pfn;
fc9b0e
+		} else {
fc9b0e
+			verbose_printf("Map succeeded at 0x%lx\n", addr);
fc9b0e
+			munmap(p, getpagesize());
fc9b0e
+			low = pfn;
fc9b0e
 		}
fc9b0e
-		munmap(p, getpagesize());
fc9b0e
-		addr += getpagesize();
fc9b0e
-#if defined(__powerpc64__)
fc9b0e
-		if (addr > (1UL << 46) && addr < (1UL << 47))
fc9b0e
-			addr = 1UL << 47;	/* 64TB */
fc9b0e
-		else if (addr > (1UL << 47) && addr < (1UL << 48))
fc9b0e
-			addr = 1UL << 48;	/* 128TB */
fc9b0e
-		else if (addr > (1UL << 48) && addr < (1UL << 49))
fc9b0e
-			addr = 1UL << 49;	/* 512TB */
fc9b0e
-		else if (addr > (1UL << 49) && addr < (1UL << 50))
fc9b0e
-			addr = 1UL << 50;	/* 1PB */
fc9b0e
-		else if (addr > (1UL << 50) && addr < (1UL << 51))
fc9b0e
-			addr = 1UL << 51;	/* 2PB */
fc9b0e
-		else if (addr > (1UL << 51) && addr < (1UL << 52))
fc9b0e
-			addr = 1UL << 52;	/* 4PB */
fc9b0e
-#endif
fc9b0e
-#if defined(__s390x__)
fc9b0e
-		if (addr > (1UL << 42) && addr < (1UL << 53))
fc9b0e
-			addr = 1UL << 53;
fc9b0e
-#endif
fc9b0e
 	}
fc9b0e
-	/* addr wrapped around */
fc9b0e
-	return 0;
fc9b0e
+
fc9b0e
+	return low * getpagesize();
fc9b0e
 }
fc9b0e
 
fc9b0e
 int main(int argc, char *argv[])
fc9b0e
-- 
fc9b0e
1.8.3.1
fc9b0e