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

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