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 /tools | |
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>
Diffstat (limited to 'tools')
-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 | } | ||