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