44 Before running this huge pages for each huge page size must have been
55 reserved.
66 For large pages beyond MAX_PAGE_ORDER (like 1GB on x86) boot options must
7- be used.
7+ be used. 1GB wouldn't be tested if it isn't available.
88 Also shmmax must be increased.
99 And you need to run as root to work around some weird permissions in shm.
1010 And nothing using huge pages should run in parallel.
2626#include <stdarg.h>
2727#include <string.h>
2828#include "vm_util.h"
29-
30- #define err (x ) perror(x), exit(1)
29+ #include "../kselftest.h"
3130
3231#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
3332#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
4443#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
4544
4645#define NUM_PAGESIZES 5
47-
4846#define NUM_PAGES 4
4947
50- #define Dprintf (fmt ...) // printf(fmt)
51-
5248unsigned long page_sizes [NUM_PAGESIZES ];
5349int num_page_sizes ;
5450
@@ -60,28 +56,15 @@ int ilog2(unsigned long v)
6056 return l ;
6157}
6258
63- void find_pagesizes (void )
64- {
65- glob_t g ;
66- int i ;
67- glob ("/sys/kernel/mm/hugepages/hugepages-*kB" , 0 , NULL , & g );
68- assert (g .gl_pathc <= NUM_PAGESIZES );
69- for (i = 0 ; i < g .gl_pathc ; i ++ ) {
70- sscanf (g .gl_pathv [i ], "/sys/kernel/mm/hugepages/hugepages-%lukB" ,
71- & page_sizes [i ]);
72- page_sizes [i ] <<= 10 ;
73- printf ("Found %luMB\n" , page_sizes [i ] >> 20 );
74- }
75- num_page_sizes = g .gl_pathc ;
76- globfree (& g );
77- }
78-
7959void show (unsigned long ps )
8060{
8161 char buf [100 ];
62+
8263 if (ps == getpagesize ())
8364 return ;
84- printf ("%luMB: " , ps >> 20 );
65+
66+ ksft_print_msg ("%luMB: " , ps >> 20 );
67+
8568 fflush (stdout );
8669 snprintf (buf , sizeof buf ,
8770 "cat /sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages" ,
@@ -105,7 +88,7 @@ unsigned long read_sysfs(int warn, char *fmt, ...)
10588 f = fopen (buf , "r" );
10689 if (!f ) {
10790 if (warn )
108- printf ("missing %s\n" , buf );
91+ ksft_print_msg ("missing %s\n" , buf );
10992 return 0 ;
11093 }
11194 if (getline (& line , & linelen , f ) > 0 ) {
@@ -119,123 +102,143 @@ unsigned long read_sysfs(int warn, char *fmt, ...)
119102unsigned long read_free (unsigned long ps )
120103{
121104 return read_sysfs (ps != getpagesize (),
122- "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages" ,
123- ps >> 10 );
105+ "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages" ,
106+ ps >> 10 );
124107}
125108
126109void test_mmap (unsigned long size , unsigned flags )
127110{
128111 char * map ;
129112 unsigned long before , after ;
130- int err ;
131113
132114 before = read_free (size );
133115 map = mmap (NULL , size * NUM_PAGES , PROT_READ |PROT_WRITE ,
134116 MAP_PRIVATE |MAP_ANONYMOUS |MAP_HUGETLB |flags , -1 , 0 );
117+ if (map == MAP_FAILED )
118+ ksft_exit_fail_msg ("mmap: %s\n" , strerror (errno ));
135119
136- if (map == (char * )-1 ) err ("mmap" );
137120 memset (map , 0xff , size * NUM_PAGES );
138121 after = read_free (size );
139- Dprintf ("before %lu after %lu diff %ld size %lu\n" ,
140- before , after , before - after , size );
141- assert (size == getpagesize () || (before - after ) == NUM_PAGES );
122+
142123 show (size );
143- err = munmap (map , size * NUM_PAGES );
144- assert (!err );
124+ ksft_test_result (size == getpagesize () || (before - after ) == NUM_PAGES ,
125+ "%s mmap\n" , __func__ );
126+
127+ if (munmap (map , size * NUM_PAGES ))
128+ ksft_exit_fail_msg ("%s: unmap %s\n" , __func__ , strerror (errno ));
145129}
146130
147131void test_shmget (unsigned long size , unsigned flags )
148132{
149133 int id ;
150134 unsigned long before , after ;
151- int err ;
135+ struct shm_info i ;
136+ char * map ;
152137
153138 before = read_free (size );
154139 id = shmget (IPC_PRIVATE , size * NUM_PAGES , IPC_CREAT |0600 |flags );
155- if (id < 0 ) err ("shmget" );
156-
157- struct shm_info i ;
158- if (shmctl (id , SHM_INFO , (void * )& i ) < 0 ) err ("shmctl" );
159- Dprintf ("alloc %lu res %lu\n" , i .shm_tot , i .shm_rss );
140+ if (id < 0 ) {
141+ if (errno == EPERM ) {
142+ ksft_test_result_skip ("shmget requires root privileges: %s\n" ,
143+ strerror (errno ));
144+ return ;
145+ }
146+ ksft_exit_fail_msg ("shmget: %s\n" , strerror (errno ));
147+ }
160148
149+ if (shmctl (id , SHM_INFO , (void * )& i ) < 0 )
150+ ksft_exit_fail_msg ("shmctl: %s\n" , strerror (errno ));
161151
162- Dprintf ( "id %d\n" , id );
163- char * map = shmat ( id , NULL , 0600 );
164- if ( map == ( char * ) -1 ) err ( "shmat" );
152+ map = shmat ( id , NULL , 0600 );
153+ if ( map == MAP_FAILED )
154+ ksft_exit_fail_msg ( "shmat: %s\n" , strerror ( errno ) );
165155
166156 shmctl (id , IPC_RMID , NULL );
167157
168158 memset (map , 0xff , size * NUM_PAGES );
169159 after = read_free (size );
170160
171- Dprintf ("before %lu after %lu diff %ld size %lu\n" ,
172- before , after , before - after , size );
173- assert (size == getpagesize () || (before - after ) == NUM_PAGES );
174161 show (size );
175- err = shmdt (map );
176- assert (!err );
162+ ksft_test_result (size == getpagesize () || (before - after ) == NUM_PAGES ,
163+ "%s: mmap\n" , __func__ );
164+ if (shmdt (map ))
165+ ksft_exit_fail_msg ("%s: shmdt: %s\n" , __func__ , strerror (errno ));
177166}
178167
179- void sanity_checks (void )
168+ void find_pagesizes (void )
180169{
181- int i ;
182170 unsigned long largest = getpagesize ();
171+ int i ;
172+ glob_t g ;
183173
184- for (i = 0 ; i < num_page_sizes ; i ++ ) {
185- if (page_sizes [i ] > largest )
174+ glob ("/sys/kernel/mm/hugepages/hugepages-*kB" , 0 , NULL , & g );
175+ assert (g .gl_pathc <= NUM_PAGESIZES );
176+ for (i = 0 ; (i < g .gl_pathc ) && (num_page_sizes < NUM_PAGESIZES ); i ++ ) {
177+ sscanf (g .gl_pathv [i ], "/sys/kernel/mm/hugepages/hugepages-%lukB" ,
178+ & page_sizes [num_page_sizes ]);
179+ page_sizes [num_page_sizes ] <<= 10 ;
180+ ksft_print_msg ("Found %luMB\n" , page_sizes [i ] >> 20 );
181+
182+ if (page_sizes [num_page_sizes ] > largest )
186183 largest = page_sizes [i ];
187184
188- if (read_free (page_sizes [i ]) < NUM_PAGES ) {
189- printf ("Not enough huge pages for page size %lu MB, need %u\n" ,
190- page_sizes [i ] >> 20 ,
191- NUM_PAGES );
192- exit (0 );
193- }
185+ if (read_free (page_sizes [num_page_sizes ]) >= NUM_PAGES )
186+ num_page_sizes ++ ;
187+ else
188+ ksft_print_msg ("SKIP for size %lu MB as not enough huge pages, need %u\n" ,
189+ page_sizes [num_page_sizes ] >> 20 , NUM_PAGES );
194190 }
191+ globfree (& g );
195192
196- if (read_sysfs (0 , "/proc/sys/kernel/shmmax" ) < NUM_PAGES * largest ) {
197- printf ("Please do echo %lu > /proc/sys/kernel/shmmax" , largest * NUM_PAGES );
198- exit (0 );
199- }
193+ if (read_sysfs (0 , "/proc/sys/kernel/shmmax" ) < NUM_PAGES * largest )
194+ ksft_exit_fail_msg ("Please do echo %lu > /proc/sys/kernel/shmmax" ,
195+ largest * NUM_PAGES );
200196
201197#if defined(__x86_64__ )
202198 if (largest != 1U <<30 ) {
203- printf ("No GB pages available on x86-64\n"
204- "Please boot with hugepagesz=1G hugepages=%d\n" , NUM_PAGES );
205- exit (0 );
199+ ksft_exit_fail_msg ("No GB pages available on x86-64\n"
200+ "Please boot with hugepagesz=1G hugepages=%d\n" , NUM_PAGES );
206201 }
207202#endif
208203}
209204
210205int main (void )
211206{
212- int i ;
213207 unsigned default_hps = default_huge_page_size ();
208+ int i ;
209+
210+ ksft_print_header ();
214211
215212 find_pagesizes ();
216213
217- sanity_checks ();
214+ if (!num_page_sizes )
215+ ksft_finished ();
216+
217+ ksft_set_plan (2 * num_page_sizes + 3 );
218218
219219 for (i = 0 ; i < num_page_sizes ; i ++ ) {
220220 unsigned long ps = page_sizes [i ];
221221 int arg = ilog2 (ps ) << MAP_HUGE_SHIFT ;
222- printf ("Testing %luMB mmap with shift %x\n" , ps >> 20 , arg );
222+
223+ ksft_print_msg ("Testing %luMB mmap with shift %x\n" , ps >> 20 , arg );
223224 test_mmap (ps , MAP_HUGETLB | arg );
224225 }
225- printf ("Testing default huge mmap\n" );
226+
227+ ksft_print_msg ("Testing default huge mmap\n" );
226228 test_mmap (default_hps , MAP_HUGETLB );
227229
228- puts ("Testing non-huge shmget" );
230+ ksft_print_msg ("Testing non-huge shmget\n " );
229231 test_shmget (getpagesize (), 0 );
230232
231233 for (i = 0 ; i < num_page_sizes ; i ++ ) {
232234 unsigned long ps = page_sizes [i ];
233235 int arg = ilog2 (ps ) << SHM_HUGE_SHIFT ;
234- printf ("Testing %luMB shmget with shift %x\n" , ps >> 20 , arg );
236+ ksft_print_msg ("Testing %luMB shmget with shift %x\n" , ps >> 20 , arg );
235237 test_shmget (ps , SHM_HUGETLB | arg );
236238 }
237- puts ("default huge shmget" );
239+
240+ ksft_print_msg ("default huge shmget\n" );
238241 test_shmget (default_hps , SHM_HUGETLB );
239242
240- return 0 ;
243+ ksft_finished () ;
241244}
0 commit comments