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