root/tools/testing/selftests/vm/map_hugetlb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_bytes
  2. write_bytes
  3. read_bytes
  4. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Example of using hugepage memory in a user application using the mmap
   4  * system call with MAP_HUGETLB flag.  Before running this program make
   5  * sure the administrator has allocated enough default sized huge pages
   6  * to cover the 256 MB allocation.
   7  *
   8  * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
   9  * That means the addresses starting with 0x800000... will need to be
  10  * specified.  Specifying a fixed address is not required on ppc64, i386
  11  * or x86_64.
  12  */
  13 #include <stdlib.h>
  14 #include <stdio.h>
  15 #include <unistd.h>
  16 #include <sys/mman.h>
  17 #include <fcntl.h>
  18 
  19 #define LENGTH (256UL*1024*1024)
  20 #define PROTECTION (PROT_READ | PROT_WRITE)
  21 
  22 #ifndef MAP_HUGETLB
  23 #define MAP_HUGETLB 0x40000 /* arch specific */
  24 #endif
  25 
  26 #ifndef MAP_HUGE_SHIFT
  27 #define MAP_HUGE_SHIFT 26
  28 #endif
  29 
  30 #ifndef MAP_HUGE_MASK
  31 #define MAP_HUGE_MASK 0x3f
  32 #endif
  33 
  34 /* Only ia64 requires this */
  35 #ifdef __ia64__
  36 #define ADDR (void *)(0x8000000000000000UL)
  37 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
  38 #else
  39 #define ADDR (void *)(0x0UL)
  40 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
  41 #endif
  42 
  43 static void check_bytes(char *addr)
  44 {
  45         printf("First hex is %x\n", *((unsigned int *)addr));
  46 }
  47 
  48 static void write_bytes(char *addr, size_t length)
  49 {
  50         unsigned long i;
  51 
  52         for (i = 0; i < length; i++)
  53                 *(addr + i) = (char)i;
  54 }
  55 
  56 static int read_bytes(char *addr, size_t length)
  57 {
  58         unsigned long i;
  59 
  60         check_bytes(addr);
  61         for (i = 0; i < length; i++)
  62                 if (*(addr + i) != (char)i) {
  63                         printf("Mismatch at %lu\n", i);
  64                         return 1;
  65                 }
  66         return 0;
  67 }
  68 
  69 int main(int argc, char **argv)
  70 {
  71         void *addr;
  72         int ret;
  73         size_t length = LENGTH;
  74         int flags = FLAGS;
  75         int shift = 0;
  76 
  77         if (argc > 1)
  78                 length = atol(argv[1]) << 20;
  79         if (argc > 2) {
  80                 shift = atoi(argv[2]);
  81                 if (shift)
  82                         flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
  83         }
  84 
  85         if (shift)
  86                 printf("%u kB hugepages\n", 1 << shift);
  87         else
  88                 printf("Default size hugepages\n");
  89         printf("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
  90 
  91         addr = mmap(ADDR, length, PROTECTION, flags, -1, 0);
  92         if (addr == MAP_FAILED) {
  93                 perror("mmap");
  94                 exit(1);
  95         }
  96 
  97         printf("Returned address is %p\n", addr);
  98         check_bytes(addr);
  99         write_bytes(addr, length);
 100         ret = read_bytes(addr, length);
 101 
 102         /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
 103         if (munmap(addr, length)) {
 104                 perror("munmap");
 105                 exit(1);
 106         }
 107 
 108         return ret;
 109 }

/* [<][>][^][v][top][bottom][index][help] */