Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
d34b661b ME |
2 | #include <stdio.h> |
3 | #include <sys/mman.h> | |
4 | #include <unistd.h> | |
5 | ||
6 | #include "utils.h" | |
7 | ||
8 | /* This must match the huge page & THP size */ | |
9 | #define SIZE (16 * 1024 * 1024) | |
10 | ||
11 | static int test_body(void) | |
12 | { | |
13 | void *addr; | |
14 | char *p; | |
15 | ||
16 | addr = (void *)0xa0000000; | |
17 | ||
18 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | |
19 | MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | |
20 | if (p != MAP_FAILED) { | |
21 | /* | |
22 | * Typically the mmap will fail because no huge pages are | |
23 | * allocated on the system. But if there are huge pages | |
24 | * allocated the mmap will succeed. That's fine too, we just | |
215ba781 DR |
25 | * munmap here before continuing. munmap() length of |
26 | * MAP_HUGETLB memory must be hugepage aligned. | |
d34b661b | 27 | */ |
215ba781 DR |
28 | if (munmap(addr, SIZE)) { |
29 | perror("munmap"); | |
30 | return 1; | |
31 | } | |
d34b661b ME |
32 | } |
33 | ||
34 | p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, | |
35 | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | |
36 | if (p == MAP_FAILED) { | |
37 | printf("Mapping failed @ %p\n", addr); | |
38 | perror("mmap"); | |
39 | return 1; | |
40 | } | |
41 | ||
42 | /* | |
43 | * Either a user or kernel access is sufficient to trigger the bug. | |
44 | * A kernel access is easier to spot & debug, as it will trigger the | |
45 | * softlockup or RCU stall detectors, and when the system is kicked | |
46 | * into xmon we get a backtrace in the kernel. | |
47 | * | |
48 | * A good option is: | |
49 | * getcwd(p, SIZE); | |
50 | * | |
51 | * For the purposes of this testcase it's preferable to spin in | |
52 | * userspace, so the harness can kill us if we get stuck. That way we | |
53 | * see a test failure rather than a dead system. | |
54 | */ | |
55 | *p = 0xf; | |
56 | ||
57 | munmap(addr, SIZE); | |
58 | ||
59 | return 0; | |
60 | } | |
61 | ||
62 | static int test_main(void) | |
63 | { | |
64 | int i; | |
65 | ||
66 | /* 10,000 because it's a "bunch", and completes reasonably quickly */ | |
67 | for (i = 0; i < 10000; i++) | |
68 | if (test_body()) | |
69 | return 1; | |
70 | ||
71 | return 0; | |
72 | } | |
73 | ||
74 | int main(void) | |
75 | { | |
76 | return test_harness(test_main, "hugetlb_vs_thp"); | |
77 | } |