diff options
Diffstat (limited to 'tools/testing/selftests/mm/khugepaged.c')
| -rw-r--r-- | tools/testing/selftests/mm/khugepaged.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c index 10e8dedcb087..c02d00846a79 100644 --- a/tools/testing/selftests/mm/khugepaged.c +++ b/tools/testing/selftests/mm/khugepaged.c @@ -51,7 +51,7 @@ struct mem_ops { void *(*setup_area)(int nr_hpages); void (*cleanup_area)(void *p, unsigned long size); void (*fault)(void *p, unsigned long start, unsigned long end); - bool (*check_huge)(void *addr, int nr_hpages); + bool (*check_huge)(void *addr, size_t len, int nr_hpages, unsigned long hpage_size); const char *name; }; @@ -276,7 +276,7 @@ static void *alloc_hpage(struct mem_ops *ops) ksft_print_msg("Allocate huge page..."); if (madvise_collapse_retry(p, hpage_pmd_size)) ksft_exit_fail_perror("madvise(MADV_COLLAPSE)"); - if (!ops->check_huge(p, 1)) + if (!ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) ksft_exit_fail_perror("madvise(MADV_COLLAPSE)"); if (madvise(p, hpage_pmd_size, MADV_HUGEPAGE)) ksft_exit_fail_perror("madvise(MADV_HUGEPAGE)"); @@ -310,9 +310,10 @@ static void anon_fault(void *p, unsigned long start, unsigned long end) fill_memory(p, start, end); } -static bool anon_check_huge(void *addr, int nr_hpages) +static bool anon_check_huge(void *addr, size_t len, int nr_hpages, + unsigned long hpage_size) { - return check_huge_anon(addr, nr_hpages, hpage_pmd_size); + return check_huge_anon(addr, len, nr_hpages, hpage_size); } static void *file_setup_area_common(int nr_hpages, enum file_setup_ops setup) @@ -412,13 +413,14 @@ static void file_fault_write(void *p, unsigned long start, unsigned long end) ksft_exit_fail_perror("madvise(MADV_POPULATE_WRITE)"); } -static bool file_check_huge(void *addr, int nr_hpages) +static bool file_check_huge(void *addr, size_t len, int nr_hpages, + unsigned long hpage_size) { switch (finfo.type) { case VMA_FILE: - return check_huge_file(addr, nr_hpages, hpage_pmd_size); + return check_huge_file(addr, len, nr_hpages, hpage_size); case VMA_SHMEM: - return check_huge_shmem(addr, nr_hpages, hpage_pmd_size); + return check_huge_shmem(addr, len, nr_hpages, hpage_size); default: exit(EXIT_FAILURE); return false; @@ -448,9 +450,10 @@ static void shmem_cleanup_area(void *p, unsigned long size) close(finfo.fd); } -static bool shmem_check_huge(void *addr, int nr_hpages) +static bool shmem_check_huge(void *addr, size_t len, int nr_hpages, + unsigned long hpage_size) { - return check_huge_shmem(addr, nr_hpages, hpage_pmd_size); + return check_huge_shmem(addr, len, nr_hpages, hpage_size); } static struct mem_ops __anon_ops = { @@ -533,7 +536,7 @@ static void __madvise_collapse(const char *msg, char *p, int nr_hpages, ret = madvise_collapse_retry(p, nr_hpages * hpage_pmd_size); if (((bool)ret) == expect) fail("Fail: Bad return value"); - else if (!ops->check_huge(p, expect ? nr_hpages : 0)) + else if (!ops->check_huge(p, nr_hpages * hpage_pmd_size, expect ? nr_hpages : 0, hpage_pmd_size)) fail("Fail: check_huge()"); else success("OK"); @@ -545,7 +548,7 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages, struct mem_ops *ops, bool expect) { /* Sanity check */ - if (!ops->check_huge(p, 0)) + if (!ops->check_huge(p, nr_hpages * hpage_pmd_size, 0, hpage_pmd_size)) ksft_exit_fail_msg("Unexpected huge page\n"); __madvise_collapse(msg, p, nr_hpages, ops, expect); } @@ -554,11 +557,12 @@ static void madvise_collapse(const char *msg, char *p, int nr_hpages, static bool wait_for_scan(const char *msg, char *p, int nr_hpages, struct mem_ops *ops) { + size_t len = nr_hpages * hpage_pmd_size; int full_scans; int timeout = 6; /* 3 seconds */ /* Sanity check */ - if (!ops->check_huge(p, 0)) + if (!ops->check_huge(p, len, 0, hpage_pmd_size)) ksft_exit_fail_msg("Unexpected huge page\n"); madvise(p, nr_hpages * hpage_pmd_size, MADV_HUGEPAGE); @@ -568,7 +572,7 @@ static bool wait_for_scan(const char *msg, char *p, int nr_hpages, ksft_print_msg("%s...", msg); while (timeout--) { - if (ops->check_huge(p, nr_hpages)) + if (ops->check_huge(p, len, nr_hpages, hpage_pmd_size)) break; if (thp_read_num("khugepaged/full_scans") >= full_scans) break; @@ -582,6 +586,8 @@ static bool wait_for_scan(const char *msg, char *p, int nr_hpages, static void khugepaged_collapse(const char *msg, char *p, int nr_hpages, struct mem_ops *ops, bool expect) { + size_t len = nr_hpages * hpage_pmd_size; + /* * read&write file collapse fails since khugepaged does not flush * the target dirty folios @@ -605,7 +611,7 @@ static void khugepaged_collapse(const char *msg, char *p, int nr_hpages, if (ops != &__anon_ops) ops->fault(p, 0, nr_hpages * hpage_pmd_size); - if (ops->check_huge(p, expect ? nr_hpages : 0)) + if (ops->check_huge(p, len, expect ? nr_hpages : 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -634,7 +640,7 @@ static void alloc_at_fault(void) p = alloc_mapping(1); *p = 1; ksft_print_msg("Allocate huge page on fault..."); - if (check_huge_anon(p, 1, hpage_pmd_size)) + if (check_huge_anon(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -643,7 +649,7 @@ static void alloc_at_fault(void) madvise(p, page_size, MADV_DONTNEED); ksft_print_msg("Split huge PMD on MADV_DONTNEED..."); - if (check_huge_anon(p, 0, hpage_pmd_size)) + if (check_huge_anon(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -815,7 +821,7 @@ static void collapse_single_pte_entry_compound(struct collapse_context *c, struc madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); ksft_print_msg("Split huge page leaving single PTE mapping compound page..."); madvise(p + page_size, hpage_pmd_size - page_size, MADV_DONTNEED); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -836,7 +842,7 @@ static void collapse_full_of_compound(struct collapse_context *c, struct mem_ops ksft_print_msg("Split huge page leaving single PTE page table full of compound pages..."); madvise(p, page_size, MADV_NOHUGEPAGE); madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -858,7 +864,7 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops for (i = 0; i < hpage_pmd_nr; i++) { madvise(BASE_ADDR, hpage_pmd_size, MADV_HUGEPAGE); ops->fault(BASE_ADDR, 0, hpage_pmd_size); - if (!ops->check_huge(BASE_ADDR, 1)) + if (!ops->check_huge(BASE_ADDR, hpage_pmd_size, 1, hpage_pmd_size)) ksft_exit_fail_msg("Failed to allocate huge page\n"); madvise(BASE_ADDR, hpage_pmd_size, MADV_NOHUGEPAGE); @@ -881,7 +887,7 @@ static void collapse_compound_extreme(struct collapse_context *c, struct mem_ops ops->cleanup_area(BASE_ADDR, hpage_pmd_size); ops->fault(p, 0, hpage_pmd_size); - if (!ops->check_huge(p, 1)) + if (!ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -903,7 +909,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) ksft_print_msg("Allocate small page..."); ops->fault(p, 0, page_size); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -911,7 +917,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) ksft_print_msg("Share small page over fork()..."); if (!fork()) { /* Do not touch settings on child exit */ - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -929,7 +935,7 @@ static void collapse_fork(struct collapse_context *c, struct mem_ops *ops) exit_status = WEXITSTATUS(wstatus); ksft_print_msg("Check if parent still has small page..."); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -947,7 +953,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o ksft_print_msg("Share huge page over fork()..."); if (!fork()) { /* Do not touch settings on child exit */ - if (ops->check_huge(p, 1)) + if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -955,7 +961,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o ksft_print_msg("Split huge page PMD in child process..."); madvise(p, page_size, MADV_NOHUGEPAGE); madvise(p, hpage_pmd_size, MADV_NOHUGEPAGE); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -976,7 +982,7 @@ static void collapse_fork_compound(struct collapse_context *c, struct mem_ops *o exit_status = WEXITSTATUS(wstatus); ksft_print_msg("Check if parent still has huge page..."); - if (ops->check_huge(p, 1)) + if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -995,7 +1001,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops ksft_print_msg("Share huge page over fork()..."); if (!fork()) { /* Do not touch settings on child exit */ - if (ops->check_huge(p, 1)) + if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -1003,7 +1009,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops ksft_print_msg("Trigger CoW on page %d of %d...", hpage_pmd_nr - max_ptes_shared - 1, hpage_pmd_nr); ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared - 1) * page_size); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -1016,7 +1022,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops hpage_pmd_nr - max_ptes_shared, hpage_pmd_nr); ops->fault(p, 0, (hpage_pmd_nr - max_ptes_shared) * page_size); - if (ops->check_huge(p, 0)) + if (ops->check_huge(p, hpage_pmd_size, 0, hpage_pmd_size)) success("OK"); else fail("Fail"); @@ -1034,7 +1040,7 @@ static void collapse_max_ptes_shared(struct collapse_context *c, struct mem_ops exit_status = WEXITSTATUS(wstatus); ksft_print_msg("Check if parent still has huge page..."); - if (ops->check_huge(p, 1)) + if (ops->check_huge(p, hpage_pmd_size, 1, hpage_pmd_size)) success("OK"); else fail("Fail"); |
