Skip to content

Commit c0f7910

Browse files
ryanhrobakpm00
authored andcommitted
selftests/mm/cow: add tests for anonymous multi-size THP
Add tests similar to the existing PMD-sized THP tests, but which operate on memory backed by (PTE-mapped) multi-size THP. This reuses all the existing infrastructure. If the test suite detects that multi-size THP is not supported by the kernel, the new tests are skipped. Link: https://lkml.kernel.org/r/20231207161211.2374093-11-ryan.roberts@arm.com Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> Reviewed-by: David Hildenbrand <david@redhat.com> Tested-by: Kefeng Wang <wangkefeng.wang@huawei.com> Tested-by: John Hubbard <jhubbard@nvidia.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Barry Song <v-songbaohua@oppo.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: David Rientjes <rientjes@google.com> Cc: "Huang, Ying" <ying.huang@intel.com> Cc: Hugh Dickins <hughd@google.com> Cc: Itaru Kitayama <itaru.kitayama@gmail.com> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Luis Chamberlain <mcgrof@kernel.org> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Yang Shi <shy828301@gmail.com> Cc: Yin Fengwei <fengwei.yin@intel.com> Cc: Yu Zhao <yuzhao@google.com> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 12dc16b commit c0f7910

File tree

1 file changed

+70
-12
lines changed
  • tools/testing/selftests/mm

1 file changed

+70
-12
lines changed

tools/testing/selftests/mm/cow.c

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,49 @@
2929
#include "../../../../mm/gup_test.h"
3030
#include "../kselftest.h"
3131
#include "vm_util.h"
32+
#include "thp_settings.h"
3233

3334
static size_t pagesize;
3435
static int pagemap_fd;
3536
static size_t pmdsize;
37+
static int nr_thpsizes;
38+
static size_t thpsizes[20];
3639
static int nr_hugetlbsizes;
3740
static size_t hugetlbsizes[10];
3841
static int gup_fd;
3942
static bool has_huge_zeropage;
4043

44+
static int sz2ord(size_t size)
45+
{
46+
return __builtin_ctzll(size / pagesize);
47+
}
48+
49+
static int detect_thp_sizes(size_t sizes[], int max)
50+
{
51+
int count = 0;
52+
unsigned long orders;
53+
size_t kb;
54+
int i;
55+
56+
/* thp not supported at all. */
57+
if (!pmdsize)
58+
return 0;
59+
60+
orders = 1UL << sz2ord(pmdsize);
61+
orders |= thp_supported_orders();
62+
63+
for (i = 0; orders && count < max; i++) {
64+
if (!(orders & (1UL << i)))
65+
continue;
66+
orders &= ~(1UL << i);
67+
kb = (pagesize >> 10) << i;
68+
sizes[count++] = kb * 1024;
69+
ksft_print_msg("[INFO] detected THP size: %zu KiB\n", kb);
70+
}
71+
72+
return count;
73+
}
74+
4175
static void detect_huge_zeropage(void)
4276
{
4377
int fd = open("/sys/kernel/mm/transparent_hugepage/use_zero_page",
@@ -1101,15 +1135,27 @@ static void run_anon_test_case(struct test_case const *test_case)
11011135

11021136
run_with_base_page(test_case->fn, test_case->desc);
11031137
run_with_base_page_swap(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);
1138+
for (i = 0; i < nr_thpsizes; i++) {
1139+
size_t size = thpsizes[i];
1140+
struct thp_settings settings = *thp_current_settings();
1141+
1142+
settings.hugepages[sz2ord(pmdsize)].enabled = THP_NEVER;
1143+
settings.hugepages[sz2ord(size)].enabled = THP_ALWAYS;
1144+
thp_push_settings(&settings);
1145+
1146+
if (size == pmdsize) {
1147+
run_with_thp(test_case->fn, test_case->desc, size);
1148+
run_with_thp_swap(test_case->fn, test_case->desc, size);
1149+
}
1150+
1151+
run_with_pte_mapped_thp(test_case->fn, test_case->desc, size);
1152+
run_with_pte_mapped_thp_swap(test_case->fn, test_case->desc, size);
1153+
run_with_single_pte_of_thp(test_case->fn, test_case->desc, size);
1154+
run_with_single_pte_of_thp_swap(test_case->fn, test_case->desc, size);
1155+
run_with_partial_mremap_thp(test_case->fn, test_case->desc, size);
1156+
run_with_partial_shared_thp(test_case->fn, test_case->desc, size);
1157+
1158+
thp_pop_settings();
11131159
}
11141160
for (i = 0; i < nr_hugetlbsizes; i++)
11151161
run_with_hugetlb(test_case->fn, test_case->desc,
@@ -1130,8 +1176,9 @@ static int tests_per_anon_test_case(void)
11301176
{
11311177
int tests = 2 + nr_hugetlbsizes;
11321178

1179+
tests += 6 * nr_thpsizes;
11331180
if (pmdsize)
1134-
tests += 8;
1181+
tests += 2;
11351182
return tests;
11361183
}
11371184

@@ -1689,16 +1736,22 @@ static int tests_per_non_anon_test_case(void)
16891736
int main(int argc, char **argv)
16901737
{
16911738
int err;
1739+
struct thp_settings default_settings;
16921740

16931741
ksft_print_header();
16941742

16951743
pagesize = getpagesize();
16961744
pmdsize = read_pmd_pagesize();
16971745
if (pmdsize) {
1746+
/* Only if THP is supported. */
1747+
thp_read_settings(&default_settings);
1748+
default_settings.hugepages[sz2ord(pmdsize)].enabled = THP_INHERIT;
1749+
thp_save_settings();
1750+
thp_push_settings(&default_settings);
1751+
16981752
ksft_print_msg("[INFO] detected PMD size: %zu KiB\n",
16991753
pmdsize / 1024);
1700-
ksft_print_msg("[INFO] detected THP size: %zu KiB\n",
1701-
pmdsize / 1024);
1754+
nr_thpsizes = detect_thp_sizes(thpsizes, ARRAY_SIZE(thpsizes));
17021755
}
17031756
nr_hugetlbsizes = detect_hugetlb_page_sizes(hugetlbsizes,
17041757
ARRAY_SIZE(hugetlbsizes));
@@ -1717,6 +1770,11 @@ int main(int argc, char **argv)
17171770
run_anon_thp_test_cases();
17181771
run_non_anon_test_cases();
17191772

1773+
if (pmdsize) {
1774+
/* Only if THP is supported. */
1775+
thp_restore_settings();
1776+
}
1777+
17201778
err = ksft_get_fail_cnt();
17211779
if (err)
17221780
ksft_exit_fail_msg("%d out of %d tests failed\n",

0 commit comments

Comments
 (0)