Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <stdio.h>
0003 #include <sys/mman.h>
0004 #include <unistd.h>
0005 
0006 #include "utils.h"
0007 
0008 /* This must match the huge page & THP size */
0009 #define SIZE    (16 * 1024 * 1024)
0010 
0011 static int test_body(void)
0012 {
0013     void *addr;
0014     char *p;
0015 
0016     addr = (void *)0xa0000000;
0017 
0018     p = mmap(addr, SIZE, PROT_READ | PROT_WRITE,
0019          MAP_HUGETLB | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
0020     if (p != MAP_FAILED) {
0021         /*
0022          * Typically the mmap will fail because no huge pages are
0023          * allocated on the system. But if there are huge pages
0024          * allocated the mmap will succeed. That's fine too, we just
0025          * munmap here before continuing.  munmap() length of
0026          * MAP_HUGETLB memory must be hugepage aligned.
0027          */
0028         if (munmap(addr, SIZE)) {
0029             perror("munmap");
0030             return 1;
0031         }
0032     }
0033 
0034     p = mmap(addr, SIZE, PROT_READ | PROT_WRITE,
0035          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
0036     if (p == MAP_FAILED) {
0037         printf("Mapping failed @ %p\n", addr);
0038         perror("mmap");
0039         return 1;
0040     }
0041 
0042     /*
0043      * Either a user or kernel access is sufficient to trigger the bug.
0044      * A kernel access is easier to spot & debug, as it will trigger the
0045      * softlockup or RCU stall detectors, and when the system is kicked
0046      * into xmon we get a backtrace in the kernel.
0047      *
0048      * A good option is:
0049      *  getcwd(p, SIZE);
0050      *
0051      * For the purposes of this testcase it's preferable to spin in
0052      * userspace, so the harness can kill us if we get stuck. That way we
0053      * see a test failure rather than a dead system.
0054      */
0055     *p = 0xf;
0056 
0057     munmap(addr, SIZE);
0058 
0059     return 0;
0060 }
0061 
0062 static int test_main(void)
0063 {
0064     int i;
0065 
0066     /* 10,000 because it's a "bunch", and completes reasonably quickly */
0067     for (i = 0; i < 10000; i++)
0068         if (test_body())
0069             return 1;
0070 
0071     return 0;
0072 }
0073 
0074 int main(void)
0075 {
0076     return test_harness(test_main, "hugetlb_vs_thp");
0077 }