Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Example of using hugepage memory in a user application using the mmap
0004  * system call with MAP_HUGETLB flag.  Before running this program make
0005  * sure the administrator has allocated enough default sized huge pages
0006  * to cover the 256 MB allocation.
0007  *
0008  * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
0009  * That means the addresses starting with 0x800000... will need to be
0010  * specified.  Specifying a fixed address is not required on ppc64, i386
0011  * or x86_64.
0012  */
0013 #include <stdlib.h>
0014 #include <stdio.h>
0015 #include <unistd.h>
0016 #include <sys/mman.h>
0017 #include <fcntl.h>
0018 
0019 #define LENGTH (256UL*1024*1024)
0020 #define PROTECTION (PROT_READ | PROT_WRITE)
0021 
0022 #ifndef MAP_HUGETLB
0023 #define MAP_HUGETLB 0x40000 /* arch specific */
0024 #endif
0025 
0026 #ifndef MAP_HUGE_SHIFT
0027 #define MAP_HUGE_SHIFT 26
0028 #endif
0029 
0030 #ifndef MAP_HUGE_MASK
0031 #define MAP_HUGE_MASK 0x3f
0032 #endif
0033 
0034 /* Only ia64 requires this */
0035 #ifdef __ia64__
0036 #define ADDR (void *)(0x8000000000000000UL)
0037 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
0038 #else
0039 #define ADDR (void *)(0x0UL)
0040 #define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
0041 #endif
0042 
0043 static void check_bytes(char *addr)
0044 {
0045     printf("First hex is %x\n", *((unsigned int *)addr));
0046 }
0047 
0048 static void write_bytes(char *addr, size_t length)
0049 {
0050     unsigned long i;
0051 
0052     for (i = 0; i < length; i++)
0053         *(addr + i) = (char)i;
0054 }
0055 
0056 static int read_bytes(char *addr, size_t length)
0057 {
0058     unsigned long i;
0059 
0060     check_bytes(addr);
0061     for (i = 0; i < length; i++)
0062         if (*(addr + i) != (char)i) {
0063             printf("Mismatch at %lu\n", i);
0064             return 1;
0065         }
0066     return 0;
0067 }
0068 
0069 int main(int argc, char **argv)
0070 {
0071     void *addr;
0072     int ret;
0073     size_t length = LENGTH;
0074     int flags = FLAGS;
0075     int shift = 0;
0076 
0077     if (argc > 1)
0078         length = atol(argv[1]) << 20;
0079     if (argc > 2) {
0080         shift = atoi(argv[2]);
0081         if (shift)
0082             flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
0083     }
0084 
0085     if (shift)
0086         printf("%u kB hugepages\n", 1 << (shift - 10));
0087     else
0088         printf("Default size hugepages\n");
0089     printf("Mapping %lu Mbytes\n", (unsigned long)length >> 20);
0090 
0091     addr = mmap(ADDR, length, PROTECTION, flags, -1, 0);
0092     if (addr == MAP_FAILED) {
0093         perror("mmap");
0094         exit(1);
0095     }
0096 
0097     printf("Returned address is %p\n", addr);
0098     check_bytes(addr);
0099     write_bytes(addr, length);
0100     ret = read_bytes(addr, length);
0101 
0102     /* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
0103     if (munmap(addr, length)) {
0104         perror("munmap");
0105         exit(1);
0106     }
0107 
0108     return ret;
0109 }