/* * hugepage_alloc_test1.c - test the availabilty of hugepages * * Written by Roland Mainz */ #include #include #include #include #include #include #include #include #include /* * Before using this Linux 5.10.0-13-rt-686-pae requires that "root" * reserves hugepages like this: * * $ printf '128' > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages * $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages * 128 * * Notes: * - Terminology: UNIX uses the term "largepages", Linux defiantly uses * "hugepages" * - the value is the number of MMU (large-/huge-)pages, NOT the number * of bytes. * - $ /usr/bin/pagesize -a # can inform you which pagesizes are * available (i686 usually has { 4k, 2M } pagesizes, SPARCv9 has * { 8k, 64k, 4M, 32M, ... } ) */ ssize_t get_number_of_free_hugepages(void) { int dirfd; int fd; char buf[256]; ssize_t numpages; ssize_t rs; /* read size */ /* * extra step here, since real-world applications likely * want to look at "nr_hugepages" etc, too */ dirfd = open("/sys/kernel/mm/hugepages/hugepages-2048kB/", O_DIRECTORY); if (dirfd < 0) { perror("open sysfs hugepage dir"); return -1; } fd = openat(dirfd, "free_hugepages", O_RDONLY); if (fd < 0) { perror("open sysfs hugepage free pages file"); (void)close(dirfd); return -1; } rs = read(fd, buf, sizeof(buf)); if (rs < 0) { perror("read error sysfs hugepage free pages file"); (void)close(dirfd); (void)close(fd); return -1; } (void)close(dirfd); (void)close(fd); buf[rs] = '\0'; #if MYDEBUG if ((rs > 0) && (buf[rs-1] == '\n')) buf[rs-1] = '\0'; (void)printf("string returned: |%s|\n", buf); #endif /* MYDEBUG */ errno = 0; numpages = strtol(buf, NULL, 10); if (errno != 0) { perror("error parsing value of free hugepages"); return -1; } return numpages; } int main(int ac, char *av[]) { void *p; int saved_errno; #define TEST_NUM_ALLOC_PAGES (32) size_t size = TEST_NUM_ALLOC_PAGES*1024*1024; ssize_t free_numpages; (void)puts("#start."); free_numpages = get_number_of_free_hugepages(); if (free_numpages < (TEST_NUM_ALLOC_PAGES+8)) { fprintf(stderr, "not enough hugepages\n"); return EXIT_FAILURE; } p = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0); saved_errno = errno; if (p == MAP_FAILED) perror("mmap"); (void)printf("map address = %lx, errno=%d\n", (unsigned long)p, (int)saved_errno); if (munmap(p, size) == -1) perror("munmap"); (void)puts("#done."); return EXIT_SUCCESS; }