From: Yijia Wang <[email protected]> The hugetlb mincore test passes the base page size as the MAP_HUGETLB mapping length. This works on systems where the default huge page size is the same as the base page size, but mmap() can fail with EINVAL before mincore() is exercised when the default huge page size is larger, such as on arm64 systems with 64K base pages and 2M huge pages.
Use the default huge page size from /proc/meminfo for the hugetlb mapping and unmap length. Keep the mincore() check scoped to one base page since the test only needs to verify the residency state before and after the mapping is touched. This also avoids changing the mincore() length to the whole huge page, which would require a larger residency vector because mincore() reports one byte per base page. Signed-off-by: Yijia Wang <[email protected]> --- Changes in v2: - Keep mincore() scoped to one base page and avoid resizing the residency vector. - Use the default huge page size only for the MAP_HUGETLB mapping and munmap(). Note: v1 was sent by mistake while I was still learning the b4/git send-email workflow as a newcomer, and it wrongly had linux-mm on Cc. Apologies for the noise. This v2 is routed through the kselftest path only. v1: https://lore.kernel.org/all/[email protected]/ .../selftests/mincore/mincore_selftest.c | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/mincore/mincore_selftest.c b/tools/testing/selftests/mincore/mincore_selftest.c index cdd022c1c..cd51420d5 100644 --- a/tools/testing/selftests/mincore/mincore_selftest.c +++ b/tools/testing/selftests/mincore/mincore_selftest.c @@ -22,6 +22,27 @@ #define MB (1UL << 20) #define FILE_SIZE (4 * MB) +static unsigned long default_huge_page_size(void) +{ + FILE *f = fopen("/proc/meminfo", "r"); + unsigned long hps = 0; + size_t linelen = 0; + char *line = NULL; + + if (!f) + return 0; + while (getline(&line, &linelen, f) > 0) { + if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) { + hps <<= 10; + break; + } + } + + free(line); + fclose(f); + return hps; +} + /* * Tests the user interface. This test triggers most of the documented @@ -139,14 +160,18 @@ TEST(check_anonymous_locked_pages) TEST(check_huge_pages) { unsigned char vec[1]; + unsigned long hpage_size; char *addr; int retval; int page_size; page_size = sysconf(_SC_PAGESIZE); + hpage_size = default_huge_page_size(); + if (!hpage_size) + hpage_size = page_size; errno = 0; - addr = mmap(NULL, page_size, PROT_READ | PROT_WRITE, + addr = mmap(NULL, hpage_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0); if (addr == MAP_FAILED) { @@ -170,7 +195,7 @@ TEST(check_huge_pages) } munlock(addr, page_size); - munmap(addr, page_size); + munmap(addr, hpage_size); } -- 2.43.0

