xref: /linux/tools/testing/selftests/mm/hugetlb-shm.c (revision 00599d4841790d05401820a96cf7edb193888b00)
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