linux/tools/testing/selftests/powerpc/mm/hugetlb_vs_thp_test.c
<<
>>
Prefs
   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
  11static 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
  62static 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
  74int main(void)
  75{
  76        return test_harness(test_main, "hugetlb_vs_thp");
  77}
  78