1a93cbee5SMike Rapoport (Microsoft) // SPDX-License-Identifier: GPL-2.0 2a93cbee5SMike Rapoport (Microsoft) /* 3a93cbee5SMike Rapoport (Microsoft) * hugetlb-shm: 4a93cbee5SMike Rapoport (Microsoft) * 5a93cbee5SMike Rapoport (Microsoft) * Example of using huge page memory in a user application using Sys V shared 6a93cbee5SMike Rapoport (Microsoft) * memory system calls. In this example the app is requesting 256MB of 7a93cbee5SMike Rapoport (Microsoft) * memory that is backed by huge pages. The application uses the flag 8a93cbee5SMike Rapoport (Microsoft) * SHM_HUGETLB in the shmget system call to inform the kernel that it is 9a93cbee5SMike Rapoport (Microsoft) * requesting huge pages. 10a93cbee5SMike Rapoport (Microsoft) * 11a93cbee5SMike Rapoport (Microsoft) * Note: The default shared memory limit is quite low on many kernels, 12a93cbee5SMike Rapoport (Microsoft) * you may need to increase it via: 13a93cbee5SMike Rapoport (Microsoft) * 14a93cbee5SMike Rapoport (Microsoft) * echo 268435456 > /proc/sys/kernel/shmmax 15a93cbee5SMike Rapoport (Microsoft) * 16a93cbee5SMike Rapoport (Microsoft) * This will increase the maximum size per shared memory segment to 256MB. 17a93cbee5SMike Rapoport (Microsoft) * The other limit that you will hit eventually is shmall which is the 18a93cbee5SMike Rapoport (Microsoft) * total amount of shared memory in pages. To set it to 16GB on a system 19a93cbee5SMike Rapoport (Microsoft) * with a 4kB pagesize do: 20a93cbee5SMike Rapoport (Microsoft) * 21a93cbee5SMike Rapoport (Microsoft) * echo 4194304 > /proc/sys/kernel/shmall 22a93cbee5SMike Rapoport (Microsoft) */ 23a93cbee5SMike Rapoport (Microsoft) 24a93cbee5SMike Rapoport (Microsoft) #include <stdlib.h> 25a93cbee5SMike Rapoport (Microsoft) #include <stdio.h> 26a93cbee5SMike Rapoport (Microsoft) #include <sys/types.h> 27a93cbee5SMike Rapoport (Microsoft) #include <sys/ipc.h> 28a93cbee5SMike Rapoport (Microsoft) #include <sys/shm.h> 29a93cbee5SMike Rapoport (Microsoft) #include <sys/mman.h> 30a93cbee5SMike Rapoport (Microsoft) 31f62c93faSMike Rapoport (Microsoft) #include "vm_util.h" 32*2d6d040cSMike Rapoport (Microsoft) #include "hugepage_settings.h" 33a93cbee5SMike Rapoport (Microsoft) 34f62c93faSMike Rapoport (Microsoft) #define LENGTH (256UL*1024*1024) 35a93cbee5SMike Rapoport (Microsoft) 36*2d6d040cSMike Rapoport (Microsoft) static void prepare(void) 37*2d6d040cSMike Rapoport (Microsoft) { 38*2d6d040cSMike Rapoport (Microsoft) unsigned long length, hugepage_size, nr; 39*2d6d040cSMike Rapoport (Microsoft) 40*2d6d040cSMike Rapoport (Microsoft) hugepage_size = default_huge_page_size(); 41*2d6d040cSMike Rapoport (Microsoft) if (!hugepage_size) 42*2d6d040cSMike Rapoport (Microsoft) ksft_exit_skip("Unable to determine huge page size\n"); 43*2d6d040cSMike Rapoport (Microsoft) 44*2d6d040cSMike Rapoport (Microsoft) length = (LENGTH + hugepage_size - 1) & ~(hugepage_size - 1); 45*2d6d040cSMike Rapoport (Microsoft) nr = length / hugepage_size; 46*2d6d040cSMike Rapoport (Microsoft) 47*2d6d040cSMike Rapoport (Microsoft) if (!hugetlb_setup_default(nr)) 48*2d6d040cSMike Rapoport (Microsoft) ksft_exit_skip("Not enough free huge pages\n"); 49*2d6d040cSMike Rapoport (Microsoft) 50*2d6d040cSMike Rapoport (Microsoft) shm_limits_prepare(length); 51*2d6d040cSMike Rapoport (Microsoft) } 52*2d6d040cSMike Rapoport (Microsoft) 53a93cbee5SMike Rapoport (Microsoft) int main(void) 54a93cbee5SMike Rapoport (Microsoft) { 55a93cbee5SMike Rapoport (Microsoft) int shmid; 56a93cbee5SMike Rapoport (Microsoft) unsigned long i; 57a93cbee5SMike Rapoport (Microsoft) char *shmaddr; 58a93cbee5SMike Rapoport (Microsoft) 59f62c93faSMike Rapoport (Microsoft) ksft_print_header(); 60f62c93faSMike Rapoport (Microsoft) ksft_set_plan(1); 61f62c93faSMike Rapoport (Microsoft) 62*2d6d040cSMike Rapoport (Microsoft) prepare(); 63*2d6d040cSMike Rapoport (Microsoft) 64a93cbee5SMike Rapoport (Microsoft) shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W); 65f62c93faSMike Rapoport (Microsoft) if (shmid < 0) 66f62c93faSMike Rapoport (Microsoft) ksft_exit_fail_perror("shmget"); 67f62c93faSMike Rapoport (Microsoft) 68f62c93faSMike Rapoport (Microsoft) ksft_print_msg("shmid: 0x%x\n", shmid); 69a93cbee5SMike Rapoport (Microsoft) 70a93cbee5SMike Rapoport (Microsoft) shmaddr = shmat(shmid, NULL, 0); 71a93cbee5SMike Rapoport (Microsoft) if (shmaddr == (char *)-1) { 72f62c93faSMike Rapoport (Microsoft) ksft_perror("Shared memory attach failure"); 73a93cbee5SMike Rapoport (Microsoft) shmctl(shmid, IPC_RMID, NULL); 74f62c93faSMike Rapoport (Microsoft) ksft_exit_fail(); 75a93cbee5SMike Rapoport (Microsoft) } 76f62c93faSMike Rapoport (Microsoft) ksft_print_msg("shmaddr: %p\n", shmaddr); 77a93cbee5SMike Rapoport (Microsoft) 78f62c93faSMike Rapoport (Microsoft) ksft_print_msg("Starting the writes:\n"); 79a93cbee5SMike Rapoport (Microsoft) for (i = 0; i < LENGTH; i++) 80f62c93faSMike Rapoport (Microsoft) shmaddr[i] = (char)(i); 81f62c93faSMike Rapoport (Microsoft) 82f62c93faSMike Rapoport (Microsoft) ksft_print_msg("Starting the Check..."); 83f62c93faSMike Rapoport (Microsoft) for (i = 0; i < LENGTH; i++) 84f62c93faSMike Rapoport (Microsoft) if (shmaddr[i] != (char)i) 85f62c93faSMike Rapoport (Microsoft) ksft_exit_fail_msg("Data mismatch at index %lu\n", i); 86f62c93faSMike Rapoport (Microsoft) ksft_print_msg("Done.\n"); 87a93cbee5SMike Rapoport (Microsoft) 88a93cbee5SMike Rapoport (Microsoft) if (shmdt((const void *)shmaddr) != 0) { 89f62c93faSMike Rapoport (Microsoft) ksft_perror("Detach failure"); 90a93cbee5SMike Rapoport (Microsoft) shmctl(shmid, IPC_RMID, NULL); 91f62c93faSMike Rapoport (Microsoft) ksft_exit_fail(); 92a93cbee5SMike Rapoport (Microsoft) } 93a93cbee5SMike Rapoport (Microsoft) 94a93cbee5SMike Rapoport (Microsoft) shmctl(shmid, IPC_RMID, NULL); 95a93cbee5SMike Rapoport (Microsoft) 96f62c93faSMike Rapoport (Microsoft) ksft_test_result_pass("hugepage using SysV shmget/shmat\n"); 97f62c93faSMike Rapoport (Microsoft) ksft_finished(); 98a93cbee5SMike Rapoport (Microsoft) } 99*2d6d040cSMike Rapoport (Microsoft) 100*2d6d040cSMike Rapoport (Microsoft) SHM_LIMITS_RESTORE() 101