GNU Linux-libre 4.19.245-gnu1
[releases.git] / tools / testing / selftests / powerpc / mm / hugetlb_vs_thp_test.c
1 // SPDX-License-Identifier: GPL-2.0
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
25                  * munmap here before continuing.  munmap() length of
26                  * MAP_HUGETLB memory must be hugepage aligned.
27                  */
28                 if (munmap(addr, SIZE)) {
29                         perror("munmap");
30                         return 1;
31                 }
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 }