3232
3333static size_t pagesize ;
3434static int pagemap_fd ;
35- static size_t thpsize ;
35+ static size_t pmdsize ;
3636static int nr_hugetlbsizes ;
3737static size_t hugetlbsizes [10 ];
3838static int gup_fd ;
@@ -734,7 +734,7 @@ enum thp_run {
734734 THP_RUN_PARTIAL_SHARED ,
735735};
736736
737- static void do_run_with_thp (test_fn fn , enum thp_run thp_run )
737+ static void do_run_with_thp (test_fn fn , enum thp_run thp_run , size_t thpsize )
738738{
739739 char * mem , * mmap_mem , * tmp , * mremap_mem = MAP_FAILED ;
740740 size_t size , mmap_size , mremap_size ;
@@ -759,11 +759,11 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run)
759759 }
760760
761761 /*
762- * Try to populate a THP. Touch the first sub-page and test if we get
763- * another sub-page populated automatically.
762+ * Try to populate a THP. Touch the first sub-page and test if
763+ * we get the last sub-page populated automatically.
764764 */
765765 mem [0 ] = 0 ;
766- if (!pagemap_is_populated (pagemap_fd , mem + pagesize )) {
766+ if (!pagemap_is_populated (pagemap_fd , mem + thpsize - pagesize )) {
767767 ksft_test_result_skip ("Did not get a THP populated\n" );
768768 goto munmap ;
769769 }
@@ -773,12 +773,14 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run)
773773 switch (thp_run ) {
774774 case THP_RUN_PMD :
775775 case THP_RUN_PMD_SWAPOUT :
776+ assert (thpsize == pmdsize );
776777 break ;
777778 case THP_RUN_PTE :
778779 case THP_RUN_PTE_SWAPOUT :
779780 /*
780781 * Trigger PTE-mapping the THP by temporarily mapping a single
781- * subpage R/O.
782+ * subpage R/O. This is a noop if the THP is not pmdsize (and
783+ * therefore already PTE-mapped).
782784 */
783785 ret = mprotect (mem + pagesize , pagesize , PROT_READ );
784786 if (ret ) {
@@ -875,52 +877,60 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run)
875877 munmap (mremap_mem , mremap_size );
876878}
877879
878- static void run_with_thp (test_fn fn , const char * desc )
880+ static void run_with_thp (test_fn fn , const char * desc , size_t size )
879881{
880- ksft_print_msg ("[RUN] %s ... with THP\n" , desc );
881- do_run_with_thp (fn , THP_RUN_PMD );
882+ ksft_print_msg ("[RUN] %s ... with THP (%zu kB)\n" ,
883+ desc , size / 1024 );
884+ do_run_with_thp (fn , THP_RUN_PMD , size );
882885}
883886
884- static void run_with_thp_swap (test_fn fn , const char * desc )
887+ static void run_with_thp_swap (test_fn fn , const char * desc , size_t size )
885888{
886- ksft_print_msg ("[RUN] %s ... with swapped-out THP\n" , desc );
887- do_run_with_thp (fn , THP_RUN_PMD_SWAPOUT );
889+ ksft_print_msg ("[RUN] %s ... with swapped-out THP (%zu kB)\n" ,
890+ desc , size / 1024 );
891+ do_run_with_thp (fn , THP_RUN_PMD_SWAPOUT , size );
888892}
889893
890- static void run_with_pte_mapped_thp (test_fn fn , const char * desc )
894+ static void run_with_pte_mapped_thp (test_fn fn , const char * desc , size_t size )
891895{
892- ksft_print_msg ("[RUN] %s ... with PTE-mapped THP\n" , desc );
893- do_run_with_thp (fn , THP_RUN_PTE );
896+ ksft_print_msg ("[RUN] %s ... with PTE-mapped THP (%zu kB)\n" ,
897+ desc , size / 1024 );
898+ do_run_with_thp (fn , THP_RUN_PTE , size );
894899}
895900
896- static void run_with_pte_mapped_thp_swap (test_fn fn , const char * desc )
901+ static void run_with_pte_mapped_thp_swap (test_fn fn , const char * desc , size_t size )
897902{
898- ksft_print_msg ("[RUN] %s ... with swapped-out, PTE-mapped THP\n" , desc );
899- do_run_with_thp (fn , THP_RUN_PTE_SWAPOUT );
903+ ksft_print_msg ("[RUN] %s ... with swapped-out, PTE-mapped THP (%zu kB)\n" ,
904+ desc , size / 1024 );
905+ do_run_with_thp (fn , THP_RUN_PTE_SWAPOUT , size );
900906}
901907
902- static void run_with_single_pte_of_thp (test_fn fn , const char * desc )
908+ static void run_with_single_pte_of_thp (test_fn fn , const char * desc , size_t size )
903909{
904- ksft_print_msg ("[RUN] %s ... with single PTE of THP\n" , desc );
905- do_run_with_thp (fn , THP_RUN_SINGLE_PTE );
910+ ksft_print_msg ("[RUN] %s ... with single PTE of THP (%zu kB)\n" ,
911+ desc , size / 1024 );
912+ do_run_with_thp (fn , THP_RUN_SINGLE_PTE , size );
906913}
907914
908- static void run_with_single_pte_of_thp_swap (test_fn fn , const char * desc )
915+ static void run_with_single_pte_of_thp_swap (test_fn fn , const char * desc , size_t size )
909916{
910- ksft_print_msg ("[RUN] %s ... with single PTE of swapped-out THP\n" , desc );
911- do_run_with_thp (fn , THP_RUN_SINGLE_PTE_SWAPOUT );
917+ ksft_print_msg ("[RUN] %s ... with single PTE of swapped-out THP (%zu kB)\n" ,
918+ desc , size / 1024 );
919+ do_run_with_thp (fn , THP_RUN_SINGLE_PTE_SWAPOUT , size );
912920}
913921
914- static void run_with_partial_mremap_thp (test_fn fn , const char * desc )
922+ static void run_with_partial_mremap_thp (test_fn fn , const char * desc , size_t size )
915923{
916- ksft_print_msg ("[RUN] %s ... with partially mremap()'ed THP\n" , desc );
917- do_run_with_thp (fn , THP_RUN_PARTIAL_MREMAP );
924+ ksft_print_msg ("[RUN] %s ... with partially mremap()'ed THP (%zu kB)\n" ,
925+ desc , size / 1024 );
926+ do_run_with_thp (fn , THP_RUN_PARTIAL_MREMAP , size );
918927}
919928
920- static void run_with_partial_shared_thp (test_fn fn , const char * desc )
929+ static void run_with_partial_shared_thp (test_fn fn , const char * desc , size_t size )
921930{
922- ksft_print_msg ("[RUN] %s ... with partially shared THP\n" , desc );
923- do_run_with_thp (fn , THP_RUN_PARTIAL_SHARED );
931+ ksft_print_msg ("[RUN] %s ... with partially shared THP (%zu kB)\n" ,
932+ desc , size / 1024 );
933+ do_run_with_thp (fn , THP_RUN_PARTIAL_SHARED , size );
924934}
925935
926936static void run_with_hugetlb (test_fn fn , const char * desc , size_t hugetlbsize )
@@ -1091,15 +1101,15 @@ static void run_anon_test_case(struct test_case const *test_case)
10911101
10921102 run_with_base_page (test_case -> fn , test_case -> desc );
10931103 run_with_base_page_swap (test_case -> fn , test_case -> desc );
1094- if (thpsize ) {
1095- run_with_thp (test_case -> fn , test_case -> desc );
1096- run_with_thp_swap (test_case -> fn , test_case -> desc );
1097- run_with_pte_mapped_thp (test_case -> fn , test_case -> desc );
1098- run_with_pte_mapped_thp_swap (test_case -> fn , test_case -> desc );
1099- run_with_single_pte_of_thp (test_case -> fn , test_case -> desc );
1100- run_with_single_pte_of_thp_swap (test_case -> fn , test_case -> desc );
1101- run_with_partial_mremap_thp (test_case -> fn , test_case -> desc );
1102- run_with_partial_shared_thp (test_case -> fn , test_case -> desc );
1104+ if (pmdsize ) {
1105+ run_with_thp (test_case -> fn , test_case -> desc , pmdsize );
1106+ run_with_thp_swap (test_case -> fn , test_case -> desc , pmdsize );
1107+ run_with_pte_mapped_thp (test_case -> fn , test_case -> desc , pmdsize );
1108+ run_with_pte_mapped_thp_swap (test_case -> fn , test_case -> desc , pmdsize );
1109+ run_with_single_pte_of_thp (test_case -> fn , test_case -> desc , pmdsize );
1110+ run_with_single_pte_of_thp_swap (test_case -> fn , test_case -> desc , pmdsize );
1111+ run_with_partial_mremap_thp (test_case -> fn , test_case -> desc , pmdsize );
1112+ run_with_partial_shared_thp (test_case -> fn , test_case -> desc , pmdsize );
11031113 }
11041114 for (i = 0 ; i < nr_hugetlbsizes ; i ++ )
11051115 run_with_hugetlb (test_case -> fn , test_case -> desc ,
@@ -1120,7 +1130,7 @@ static int tests_per_anon_test_case(void)
11201130{
11211131 int tests = 2 + nr_hugetlbsizes ;
11221132
1123- if (thpsize )
1133+ if (pmdsize )
11241134 tests += 8 ;
11251135 return tests ;
11261136}
@@ -1329,7 +1339,7 @@ static void run_anon_thp_test_cases(void)
13291339{
13301340 int i ;
13311341
1332- if (!thpsize )
1342+ if (!pmdsize )
13331343 return ;
13341344
13351345 ksft_print_msg ("[INFO] Anonymous THP tests\n" );
@@ -1338,13 +1348,13 @@ static void run_anon_thp_test_cases(void)
13381348 struct test_case const * test_case = & anon_thp_test_cases [i ];
13391349
13401350 ksft_print_msg ("[RUN] %s\n" , test_case -> desc );
1341- do_run_with_thp (test_case -> fn , THP_RUN_PMD );
1351+ do_run_with_thp (test_case -> fn , THP_RUN_PMD , pmdsize );
13421352 }
13431353}
13441354
13451355static int tests_per_anon_thp_test_case (void )
13461356{
1347- return thpsize ? 1 : 0 ;
1357+ return pmdsize ? 1 : 0 ;
13481358}
13491359
13501360typedef void (* non_anon_test_fn )(char * mem , const char * smem , size_t size );
@@ -1419,7 +1429,7 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
14191429 }
14201430
14211431 /* For alignment purposes, we need twice the thp size. */
1422- mmap_size = 2 * thpsize ;
1432+ mmap_size = 2 * pmdsize ;
14231433 mmap_mem = mmap (NULL , mmap_size , PROT_READ | PROT_WRITE ,
14241434 MAP_PRIVATE | MAP_ANONYMOUS , -1 , 0 );
14251435 if (mmap_mem == MAP_FAILED ) {
@@ -1434,11 +1444,11 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
14341444 }
14351445
14361446 /* We need a THP-aligned memory area. */
1437- mem = (char * )(((uintptr_t )mmap_mem + thpsize ) & ~(thpsize - 1 ));
1438- smem = (char * )(((uintptr_t )mmap_smem + thpsize ) & ~(thpsize - 1 ));
1447+ mem = (char * )(((uintptr_t )mmap_mem + pmdsize ) & ~(pmdsize - 1 ));
1448+ smem = (char * )(((uintptr_t )mmap_smem + pmdsize ) & ~(pmdsize - 1 ));
14391449
1440- ret = madvise (mem , thpsize , MADV_HUGEPAGE );
1441- ret |= madvise (smem , thpsize , MADV_HUGEPAGE );
1450+ ret = madvise (mem , pmdsize , MADV_HUGEPAGE );
1451+ ret |= madvise (smem , pmdsize , MADV_HUGEPAGE );
14421452 if (ret ) {
14431453 ksft_test_result_fail ("MADV_HUGEPAGE failed\n" );
14441454 goto munmap ;
@@ -1457,7 +1467,7 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
14571467 goto munmap ;
14581468 }
14591469
1460- fn (mem , smem , thpsize );
1470+ fn (mem , smem , pmdsize );
14611471munmap :
14621472 munmap (mmap_mem , mmap_size );
14631473 if (mmap_smem != MAP_FAILED )
@@ -1650,7 +1660,7 @@ static void run_non_anon_test_case(struct non_anon_test_case const *test_case)
16501660 run_with_zeropage (test_case -> fn , test_case -> desc );
16511661 run_with_memfd (test_case -> fn , test_case -> desc );
16521662 run_with_tmpfile (test_case -> fn , test_case -> desc );
1653- if (thpsize )
1663+ if (pmdsize )
16541664 run_with_huge_zeropage (test_case -> fn , test_case -> desc );
16551665 for (i = 0 ; i < nr_hugetlbsizes ; i ++ )
16561666 run_with_memfd_hugetlb (test_case -> fn , test_case -> desc ,
@@ -1671,7 +1681,7 @@ static int tests_per_non_anon_test_case(void)
16711681{
16721682 int tests = 3 + nr_hugetlbsizes ;
16731683
1674- if (thpsize )
1684+ if (pmdsize )
16751685 tests += 1 ;
16761686 return tests ;
16771687}
@@ -1683,10 +1693,13 @@ int main(int argc, char **argv)
16831693 ksft_print_header ();
16841694
16851695 pagesize = getpagesize ();
1686- thpsize = read_pmd_pagesize ();
1687- if (thpsize )
1696+ pmdsize = read_pmd_pagesize ();
1697+ if (pmdsize ) {
1698+ ksft_print_msg ("[INFO] detected PMD size: %zu KiB\n" ,
1699+ pmdsize / 1024 );
16881700 ksft_print_msg ("[INFO] detected THP size: %zu KiB\n" ,
1689- thpsize / 1024 );
1701+ pmdsize / 1024 );
1702+ }
16901703 nr_hugetlbsizes = detect_hugetlb_page_sizes (hugetlbsizes ,
16911704 ARRAY_SIZE (hugetlbsizes ));
16921705 detect_huge_zeropage ();
0 commit comments