diff options
| author | Michael Ellerman <mpe@ellerman.id.au> | 2014-05-28 04:21:18 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-06-05 23:55:04 -0400 |
| commit | d34b661b10ab49c9058cd6602fd0162ba6db40a3 (patch) | |
| tree | c2cb021b5db8aeaec1ff1981e8abbce6bae72973 | |
| parent | 09567e7fd44291bfc08accfdd67ad8f467842332 (diff) | |
selftests/powerpc: Test the THP bug we fixed in the previous commit
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
| -rw-r--r-- | tools/testing/selftests/powerpc/Makefile | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/powerpc/mm/Makefile | 18 | ||||
| -rw-r--r-- | tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c | 72 |
3 files changed, 91 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 316194f26ff4..b3dbe9ef1a40 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
| @@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR | |||
| 13 | 13 | ||
| 14 | export CC CFLAGS | 14 | export CC CFLAGS |
| 15 | 15 | ||
| 16 | TARGETS = pmu copyloops | 16 | TARGETS = pmu copyloops mm |
| 17 | 17 | ||
| 18 | endif | 18 | endif |
| 19 | 19 | ||
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile new file mode 100644 index 000000000000..357ccbd6bad9 --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/Makefile | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | noarg: | ||
| 2 | $(MAKE) -C ../ | ||
| 3 | |||
| 4 | PROGS := hugetlb_vs_thp_test | ||
| 5 | |||
| 6 | all: $(PROGS) | ||
| 7 | |||
| 8 | $(PROGS): ../harness.c | ||
| 9 | |||
| 10 | run_tests: all | ||
| 11 | @-for PROG in $(PROGS); do \ | ||
| 12 | ./$$PROG; \ | ||
| 13 | done; | ||
| 14 | |||
| 15 | clean: | ||
| 16 | rm -f $(PROGS) | ||
| 17 | |||
| 18 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c new file mode 100644 index 000000000000..3d8e5b033e1d --- /dev/null +++ b/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <sys/mman.h> | ||
| 3 | #include <unistd.h> | ||
| 4 | |||
| 5 | #include "utils.h" | ||
| 6 | |||
| 7 | /* This must match the huge page & THP size */ | ||
| 8 | #define SIZE (16 * 1024 * 1024) | ||
| 9 | |||
| 10 | static int test_body(void) | ||
| 11 | { | ||
| 12 | void *addr; | ||
| 13 | char *p; | ||
| 14 | |||
| 15 | addr = (void *)0xa0000000; | ||
| 16 | |||
| 17 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | ||
| 18 | MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
| 19 | if (p != MAP_FAILED) { | ||
| 20 | /* | ||
| 21 | * Typically the mmap will fail because no huge pages are | ||
| 22 | * allocated on the system. But if there are huge pages | ||
| 23 | * allocated the mmap will succeed. That's fine too, we just | ||
| 24 | * munmap here before continuing. | ||
| 25 | */ | ||
| 26 | munmap(addr, SIZE); | ||
| 27 | } | ||
| 28 | |||
| 29 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | ||
| 30 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | ||
| 31 | if (p == MAP_FAILED) { | ||
| 32 | printf("Mapping failed @ %p\n", addr); | ||
| 33 | perror("mmap"); | ||
| 34 | return 1; | ||
| 35 | } | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Either a user or kernel access is sufficient to trigger the bug. | ||
| 39 | * A kernel access is easier to spot & debug, as it will trigger the | ||
| 40 | * softlockup or RCU stall detectors, and when the system is kicked | ||
| 41 | * into xmon we get a backtrace in the kernel. | ||
| 42 | * | ||
| 43 | * A good option is: | ||
| 44 | * getcwd(p, SIZE); | ||
| 45 | * | ||
| 46 | * For the purposes of this testcase it's preferable to spin in | ||
| 47 | * userspace, so the harness can kill us if we get stuck. That way we | ||
| 48 | * see a test failure rather than a dead system. | ||
| 49 | */ | ||
| 50 | *p = 0xf; | ||
| 51 | |||
| 52 | munmap(addr, SIZE); | ||
| 53 | |||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | static int test_main(void) | ||
| 58 | { | ||
| 59 | int i; | ||
| 60 | |||
| 61 | /* 10,000 because it's a "bunch", and completes reasonably quickly */ | ||
| 62 | for (i = 0; i < 10000; i++) | ||
| 63 | if (test_body()) | ||
| 64 | return 1; | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | int main(void) | ||
| 70 | { | ||
| 71 | return test_harness(test_main, "hugetlb_vs_thp"); | ||
| 72 | } | ||
