1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * hugepage-mmap:
4 *
5 * Example of using huge page memory in a user application using the mmap
6 * system call. Before running this application, make sure that the
7 * administrator has mounted the hugetlbfs filesystem (on some directory
8 * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
9 * example, the app is requesting memory of size 256MB that is backed by
10 * huge pages.
11 */
12 #define _GNU_SOURCE
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <unistd.h>
16 #include <sys/mman.h>
17 #include <fcntl.h>
18 #include "../kselftest.h"
19
20 #define LENGTH (256UL*1024*1024)
21 #define PROTECTION (PROT_READ | PROT_WRITE)
22
check_bytes(char * addr)23 static void check_bytes(char *addr)
24 {
25 ksft_print_msg("First hex is %x\n", *((unsigned int *)addr));
26 }
27
write_bytes(char * addr)28 static void write_bytes(char *addr)
29 {
30 unsigned long i;
31
32 for (i = 0; i < LENGTH; i++)
33 *(addr + i) = (char)i;
34 }
35
read_bytes(char * addr)36 static int read_bytes(char *addr)
37 {
38 unsigned long i;
39
40 check_bytes(addr);
41 for (i = 0; i < LENGTH; i++)
42 if (*(addr + i) != (char)i) {
43 ksft_print_msg("Error: Mismatch at %lu\n", i);
44 return 1;
45 }
46 return 0;
47 }
48
main(void)49 int main(void)
50 {
51 void *addr;
52 int fd, ret;
53
54 ksft_print_header();
55 ksft_set_plan(1);
56
57 fd = memfd_create("hugepage-mmap", MFD_HUGETLB);
58 if (fd < 0)
59 ksft_exit_fail_msg("memfd_create() failed: %s\n", strerror(errno));
60
61 addr = mmap(NULL, LENGTH, PROTECTION, MAP_SHARED, fd, 0);
62 if (addr == MAP_FAILED) {
63 close(fd);
64 ksft_exit_fail_msg("mmap(): %s\n", strerror(errno));
65 }
66
67 ksft_print_msg("Returned address is %p\n", addr);
68 check_bytes(addr);
69 write_bytes(addr);
70 ret = read_bytes(addr);
71
72 munmap(addr, LENGTH);
73 close(fd);
74
75 ksft_test_result(!ret, "Read same data\n");
76
77 ksft_exit(!ret);
78 }
79