@@ -118,6 +118,48 @@ static unsigned long long get_mmap_min_addr(void)
118
118
return addr ;
119
119
}
120
120
121
+ /*
122
+ * This test validates that merge is called when expanding a mapping.
123
+ * Mapping containing three pages is created, middle page is unmapped
124
+ * and then the mapping containing the first page is expanded so that
125
+ * it fills the created hole. The two parts should merge creating
126
+ * single mapping with three pages.
127
+ */
128
+ static void mremap_expand_merge (unsigned long page_size )
129
+ {
130
+ char * test_name = "mremap expand merge" ;
131
+ FILE * fp ;
132
+ char * line = NULL ;
133
+ size_t len = 0 ;
134
+ bool success = false;
135
+
136
+ char * start = mmap (NULL , 3 * page_size , PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
137
+ munmap (start + page_size , page_size );
138
+ mremap (start , page_size , 2 * page_size , 0 );
139
+
140
+ fp = fopen ("/proc/self/maps" , "r" );
141
+ if (fp == NULL ) {
142
+ ksft_test_result_fail ("%s\n" , test_name );
143
+ return ;
144
+ }
145
+
146
+ while (getline (& line , & len , fp ) != -1 ) {
147
+ char * first = strtok (line ,"- " );
148
+ void * first_val = (void * ) strtol (first , NULL , 16 );
149
+ char * second = strtok (NULL ,"- " );
150
+ void * second_val = (void * ) strtol (second , NULL , 16 );
151
+ if (first_val == start && second_val == start + 3 * page_size ) {
152
+ success = true;
153
+ break ;
154
+ }
155
+ }
156
+ if (success )
157
+ ksft_test_result_pass ("%s\n" , test_name );
158
+ else
159
+ ksft_test_result_fail ("%s\n" , test_name );
160
+ fclose (fp );
161
+ }
162
+
121
163
/*
122
164
* Returns the start address of the mapping on success, else returns
123
165
* NULL on failure.
@@ -336,6 +378,7 @@ int main(int argc, char **argv)
336
378
int i , run_perf_tests ;
337
379
unsigned int threshold_mb = VALIDATION_DEFAULT_THRESHOLD ;
338
380
unsigned int pattern_seed ;
381
+ int num_expand_tests = 1 ;
339
382
struct test test_cases [MAX_TEST ];
340
383
struct test perf_test_cases [MAX_PERF_TEST ];
341
384
int page_size ;
@@ -407,12 +450,14 @@ int main(int argc, char **argv)
407
450
(threshold_mb * _1MB >= _1GB );
408
451
409
452
ksft_set_plan (ARRAY_SIZE (test_cases ) + (run_perf_tests ?
410
- ARRAY_SIZE (perf_test_cases ) : 0 ));
453
+ ARRAY_SIZE (perf_test_cases ) : 0 ) + num_expand_tests );
411
454
412
455
for (i = 0 ; i < ARRAY_SIZE (test_cases ); i ++ )
413
456
run_mremap_test_case (test_cases [i ], & failures , threshold_mb ,
414
457
pattern_seed );
415
458
459
+ mremap_expand_merge (page_size );
460
+
416
461
if (run_perf_tests ) {
417
462
ksft_print_msg ("\n%s\n" ,
418
463
"mremap HAVE_MOVE_PMD/PUD optimization time comparison for 1GB region:" );
0 commit comments