diff options
author | Arthur She <arthur.she@linaro.org> | 2014-09-18 14:16:56 -0700 |
---|---|---|
committer | Arthur She <arthur.she@linaro.org> | 2014-09-18 14:16:56 -0700 |
commit | 39e0e0dcb02d948940c79466c302b3db4c60f3d0 (patch) | |
tree | 117c21aa0b42865a321b078ddb71c410506c51c9 /powerpc/mm/hugetlb_vs_thp_test.c | |
parent | c92da2541205425c520bc856dc6c87211c12595a (diff) |
Update to d9773ceabfaf3f27b8a36fac035b74ee599df900 from repo git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git branch masterd9773ceabfaf3f27b8a36fac035b74ee599df900linux-mainline
Diffstat (limited to 'powerpc/mm/hugetlb_vs_thp_test.c')
-rw-r--r-- | powerpc/mm/hugetlb_vs_thp_test.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/powerpc/mm/hugetlb_vs_thp_test.c b/powerpc/mm/hugetlb_vs_thp_test.c new file mode 100644 index 0000000..3d8e5b0 --- /dev/null +++ b/powerpc/mm/hugetlb_vs_thp_test.c @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <sys/mman.h> +#include <unistd.h> + +#include "utils.h" + +/* This must match the huge page & THP size */ +#define SIZE (16 * 1024 * 1024) + +static int test_body(void) +{ + void *addr; + char *p; + + addr = (void *)0xa0000000; + + p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, + MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (p != MAP_FAILED) { + /* + * Typically the mmap will fail because no huge pages are + * allocated on the system. But if there are huge pages + * allocated the mmap will succeed. That's fine too, we just + * munmap here before continuing. + */ + munmap(addr, SIZE); + } + + p = mmap(addr, SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (p == MAP_FAILED) { + printf("Mapping failed @ %p\n", addr); + perror("mmap"); + return 1; + } + + /* + * Either a user or kernel access is sufficient to trigger the bug. + * A kernel access is easier to spot & debug, as it will trigger the + * softlockup or RCU stall detectors, and when the system is kicked + * into xmon we get a backtrace in the kernel. + * + * A good option is: + * getcwd(p, SIZE); + * + * For the purposes of this testcase it's preferable to spin in + * userspace, so the harness can kill us if we get stuck. That way we + * see a test failure rather than a dead system. + */ + *p = 0xf; + + munmap(addr, SIZE); + + return 0; +} + +static int test_main(void) +{ + int i; + + /* 10,000 because it's a "bunch", and completes reasonably quickly */ + for (i = 0; i < 10000; i++) + if (test_body()) + return 1; + + return 0; +} + +int main(void) +{ + return test_harness(test_main, "hugetlb_vs_thp"); +} |