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