Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / testing / selftests / powerpc / mm / hugetlb_vs_thp_test.c
diff --git a/kernel/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c b/kernel/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c
new file mode 100644 (file)
index 0000000..4900367
--- /dev/null
@@ -0,0 +1,76 @@
+#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() length of
+                * MAP_HUGETLB memory must be hugepage aligned.
+                */
+               if (munmap(addr, SIZE)) {
+                       perror("munmap");
+                       return 1;
+               }
+       }
+
+       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");
+}