pastebin - collaborative debugging tool
rovema.kpaste.net RSS


Linux hugepage alloc demo1
Posted by Anonymous on Tue 6th Sep 2022 15:27
raw | new post
modification of post by Anonymous (view diff)

  1. /*
  2.  * hugepage_alloc_test1.c - test the availabilty of
  3.  * largepages/hugepages
  4.  *
  5.  * Written by Roland Mainz <roland.mainz@nrubsig.org>
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <stdbool.h>
  11. #include <errno.h>
  12. #include <fcntl.h>
  13. #include <unistd.h>
  14.  
  15. #include <sys/mman.h>
  16. #include <sys/stat.h>
  17.  
  18. #include <linux/mman.h>
  19.  
  20. /*
  21.  * Before using this Linux 5.10.0-13-rt-686-pae requires that "root"
  22.  * reserves hugepages like this:
  23.  *
  24.  * $ printf '128' > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
  25.  * $ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
  26.  * 128
  27.  *
  28.  * Notes:
  29.  * - Terminology: UNIX uses the term "largepages", Linux defiantly
  30.  * uses "hugepages"
  31.  * - the value is the number of MMU (large-/huge-)pages, NOT the
  32.  * number of bytes.
  33.  * - $ /usr/bin/pagesize -a # can inform you which pagesizes are
  34.  * available (i686 usually has { 4k, 2M } pagesizes, SPARCv9 has
  35.  * { 8k, 64k, 4M, 32M, ... } )
  36.  */
  37.  
  38. /* Linux-specific version */
  39. ssize_t get_number_of_free_hugepages(void)
  40. {
  41.         int     dirfd;
  42.         int     fd;
  43.         /*
  44.          * |round(log10(18446744073709551615))| is |19| on a 64bit
  45.          * system, so |128| should be enough (including sign)
  46.          */
  47.         char    buf[128];
  48.         ssize_t numpages;
  49.         ssize_t rs; /* read size */
  50.        
  51.         /*
  52.          * extra step here, since real-world applications likely
  53.          * want to look at "nr_hugepages" etc, too
  54.          */
  55.         dirfd = open("/sys/kernel/mm/hugepages/hugepages-2048kB/",
  56.                 O_DIRECTORY);
  57.         if (dirfd < 0) {
  58.                 perror("open sysfs hugepage dir");
  59.                 return -1;
  60.         }
  61.        
  62.         fd = openat(dirfd, "free_hugepages", O_RDONLY);
  63.         if (fd < 0) {
  64.                 perror("open sysfs hugepage free pages file");
  65.                 (void)close(dirfd);
  66.                 return -1;
  67.         }
  68.         rs = read(fd, buf, sizeof(buf));
  69.         if (rs < 0) {
  70.                 perror("read error sysfs hugepage free pages file");
  71.                 (void)close(dirfd);
  72.                 (void)close(fd);
  73.                 return -1;
  74.         }
  75.  
  76.         (void)close(dirfd);
  77.         (void)close(fd);
  78.        
  79.         buf[rs] = '\0';
  80. #if MYDEBUG
  81.         if ((rs > 0) && (buf[rs-1] == '\n'))
  82.                 buf[rs-1] = '\0';
  83.         (void)printf("string returned: |%s|\n", buf);
  84. #endif /* MYDEBUG */
  85.  
  86.         errno = 0;
  87.         numpages = strtol(buf, NULL, 10);
  88.         if (errno != 0) {
  89.                 perror("error parsing value of free hugepages");
  90.                 return -1;
  91.         }
  92.        
  93.         return numpages;
  94. }
  95.  
  96.  
  97. int main(int ac, char *av[])
  98. {
  99.         void            *p;
  100.         int             saved_errno;
  101. #define TEST_NUM_ALLOC_PAGES (32)
  102.         const size_t    size = TEST_NUM_ALLOC_PAGES*1024*1024;
  103.         ssize_t         free_numpages;
  104.  
  105.         (void)puts("#start.");
  106.        
  107.         free_numpages = get_number_of_free_hugepages();
  108.  
  109.         if (free_numpages < (TEST_NUM_ALLOC_PAGES+8)) {
  110.                 (void)fprintf(stderr,
  111.                         "not enough hugepages, currently free %ld\n",
  112.                         (long)free_numpages);
  113.                 return EXIT_FAILURE;
  114.         }
  115.  
  116.         /* get mmap()'ed memory with hugepage attribute */
  117.         p = mmap(0,
  118.                 size,
  119.                 PROT_READ|PROT_WRITE,
  120.                 MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, -1, 0);
  121.         saved_errno = errno;
  122.         if (p == MAP_FAILED) {
  123.                 perror("mmap");
  124.                 return EXIT_FAILURE;
  125.         }
  126.  
  127.         (void)printf("map address = 0x%lx, errno=%d\n",
  128.                 (unsigned long)p, (int)saved_errno);
  129.  
  130.         /* use memory */
  131.         volatile unsigned char *c = p;
  132.         for (size_t i = 0 ; i < size ; i++) {
  133.                 c[i] = (unsigned char)(i % 255);
  134.         }
  135.        
  136. #if MYDEBUG_USE_PROC_SMAPS
  137.         /*
  138.          * Wait here so we can check out
  139.          * $ cat /proc/$mypid/smaps | fgrep -i huge #
  140.          */
  141.         sleep(1000);
  142. #endif /* MYDEBUG_USE_PROC_SMAPS */
  143.  
  144.         if (munmap(p, size) == -1)
  145.                 perror("munmap");
  146.        
  147.         (void)puts("#done.");
  148.  
  149.         return EXIT_SUCCESS;
  150. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at