hugepage-shm.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * hugepage-shm:
  4. *
  5. * Example of using huge page memory in a user application using Sys V shared
  6. * memory system calls. In this example the app is requesting 256MB of
  7. * memory that is backed by huge pages. The application uses the flag
  8. * SHM_HUGETLB in the shmget system call to inform the kernel that it is
  9. * requesting huge pages.
  10. *
  11. * For the ia64 architecture, the Linux kernel reserves Region number 4 for
  12. * huge pages. That means that if one requires a fixed address, a huge page
  13. * aligned address starting with 0x800000... will be required. If a fixed
  14. * address is not required, the kernel will select an address in the proper
  15. * range.
  16. * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
  17. *
  18. * Note: The default shared memory limit is quite low on many kernels,
  19. * you may need to increase it via:
  20. *
  21. * echo 268435456 > /proc/sys/kernel/shmmax
  22. *
  23. * This will increase the maximum size per shared memory segment to 256MB.
  24. * The other limit that you will hit eventually is shmall which is the
  25. * total amount of shared memory in pages. To set it to 16GB on a system
  26. * with a 4kB pagesize do:
  27. *
  28. * echo 4194304 > /proc/sys/kernel/shmall
  29. */
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <sys/types.h>
  33. #include <sys/ipc.h>
  34. #include <sys/shm.h>
  35. #include <sys/mman.h>
  36. #ifndef SHM_HUGETLB
  37. #define SHM_HUGETLB 04000
  38. #endif
  39. #define LENGTH (256UL*1024*1024)
  40. #define dprintf(x) printf(x)
  41. /* Only ia64 requires this */
  42. #ifdef __ia64__
  43. #define ADDR (void *)(0x8000000000000000UL)
  44. #define SHMAT_FLAGS (SHM_RND)
  45. #else
  46. #define ADDR (void *)(0x0UL)
  47. #define SHMAT_FLAGS (0)
  48. #endif
  49. int main(void)
  50. {
  51. int shmid;
  52. unsigned long i;
  53. char *shmaddr;
  54. shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
  55. if (shmid < 0) {
  56. perror("shmget");
  57. exit(1);
  58. }
  59. printf("shmid: 0x%x\n", shmid);
  60. shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
  61. if (shmaddr == (char *)-1) {
  62. perror("Shared memory attach failure");
  63. shmctl(shmid, IPC_RMID, NULL);
  64. exit(2);
  65. }
  66. printf("shmaddr: %p\n", shmaddr);
  67. dprintf("Starting the writes:\n");
  68. for (i = 0; i < LENGTH; i++) {
  69. shmaddr[i] = (char)(i);
  70. if (!(i % (1024 * 1024)))
  71. dprintf(".");
  72. }
  73. dprintf("\n");
  74. dprintf("Starting the Check...");
  75. for (i = 0; i < LENGTH; i++)
  76. if (shmaddr[i] != (char)i) {
  77. printf("\nIndex %lu mismatched\n", i);
  78. exit(3);
  79. }
  80. dprintf("Done.\n");
  81. if (shmdt((const void *)shmaddr) != 0) {
  82. perror("Detach failure");
  83. shmctl(shmid, IPC_RMID, NULL);
  84. exit(4);
  85. }
  86. shmctl(shmid, IPC_RMID, NULL);
  87. return 0;
  88. }