Neither hint may be applied to hugetlb memory, so madvise(2) must fail with EINVAL for a hugetlb VMA. Locked VMAs are already checked here and PFNMAP VMAs by the pfnmap test.
Check the hugetlb case for both hints. run_vmtests.sh does not reserve hugetlb pages, so when run as root main() reserves the one page the test needs, and restores the pool on exit. Otherwise the test skips if no page is free. Signed-off-by: Gregory Price (Meta) <[email protected]> Reviewed-by: Sarthak Sharma <[email protected]> --- v3: Kept Sarthak's Reviewed-by, but only a couple minor changes, e.g. the hugetlb reservations / skips. --- .../testing/selftests/mm/madv_cold_pageout.c | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/testing/selftests/mm/madv_cold_pageout.c b/tools/testing/selftests/mm/madv_cold_pageout.c index 8cbbfd4c24c4..0874726ec141 100644 --- a/tools/testing/selftests/mm/madv_cold_pageout.c +++ b/tools/testing/selftests/mm/madv_cold_pageout.c @@ -141,6 +141,29 @@ TEST_F(madv_cold_pageout, locked_vma_is_rejected) ASSERT_EQ(munmap(mapping, page_size), 0); } +/* Neither hint may be applied to hugetlb memory. */ +TEST_F(madv_cold_pageout, hugetlb_vma_is_rejected) +{ + size_t size = default_huge_page_size(); + char *mapping; + + if (!size) + SKIP(return, "hugetlb is not supported"); + mapping = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); + if (mapping == MAP_FAILED) + SKIP(return, "no hugetlb pages are available"); + mapping[0] = 1; + + ASSERT_EQ(madvise(mapping, size, MADV_COLD), -1); + ASSERT_EQ(errno, EINVAL); + ASSERT_EQ(madvise(mapping, size, MADV_PAGEOUT), -1); + ASSERT_EQ(errno, EINVAL); + ASSERT_EQ(mapping[0], 1); + + ASSERT_EQ(munmap(mapping, size), 0); +} + /* A zero-length range is accepted. */ TEST_F(madv_cold_pageout, zero_length_is_accepted) { @@ -276,6 +299,9 @@ int main(int argc, char **argv) page_size = getpagesize(); /* The harness forks each test, which inherits this. */ pin_to_current_cpu(); + /* Only root can reserve the page that hugetlb_vma_is_rejected maps. */ + if (!geteuid()) + hugetlb_setup_default(1); pagemap_fd = open("/proc/self/pagemap", O_RDONLY); if (pagemap_fd < 0) -- 2.56.0
