mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 11:11:26 +02:00
selftests/mm: hugetlb-madvise: use kselftest framework
Convert hugetlb-madvise test to use kselftest framework for reporting and tracking successful and failing runs. While on it fix the check for base page size detection to actually use base_page_size. Link: https://lore.kernel.org/20260511162840.375890-11-rppt@kernel.org Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Reviewed-by: Donet Tom <donettom@linux.ibm.com> Tested-by: Sarthak Sharma <sarthak.sharma@arm.com> Tested-by: Luiz Capitulino <luizcap@redhat.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Barry Song <baohua@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Lance Yang <lance.yang@linux.dev> Cc: Leon Romanovsky <leon@kernel.org> Cc: Liam Howlett <liam@infradead.org> Cc: Li Wang <li.wang@linux.dev> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Mark Brown <broonie@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Nico Pache <npache@redhat.com> Cc: Peter Xu <peterx@redhat.com> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Shuah Khan <shuah@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
40e9e3d760
commit
83ccc26e5e
|
|
@ -26,12 +26,11 @@
|
|||
|
||||
#define validate_free_pages(exp_free) \
|
||||
do { \
|
||||
int fhp = get_free_hugepages(); \
|
||||
if (fhp != (exp_free)) { \
|
||||
printf("Unexpected number of free huge " \
|
||||
"pages line %d\n", __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
unsigned long fhp = get_free_hugepages(); \
|
||||
if (fhp != (exp_free)) \
|
||||
ksft_exit_fail_msg("Unexpected number of free " \
|
||||
"huge pages %lu, expected %lu line %d\n", \
|
||||
fhp, (exp_free), __LINE__); \
|
||||
} while (0)
|
||||
|
||||
unsigned long huge_page_size;
|
||||
|
|
@ -57,28 +56,24 @@ int main(int argc, char **argv)
|
|||
int fd;
|
||||
int ret;
|
||||
|
||||
ksft_print_header();
|
||||
ksft_set_plan(1);
|
||||
|
||||
huge_page_size = default_huge_page_size();
|
||||
if (!huge_page_size) {
|
||||
printf("Unable to determine huge page size, exiting!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!huge_page_size)
|
||||
ksft_exit_skip("Unable to determine huge page size\n");
|
||||
|
||||
base_page_size = sysconf(_SC_PAGE_SIZE);
|
||||
if (!huge_page_size) {
|
||||
printf("Unable to determine base page size, exiting!\n");
|
||||
exit(1);
|
||||
}
|
||||
if (!base_page_size)
|
||||
ksft_exit_fail_msg("Unable to determine base page size\n");
|
||||
|
||||
free_hugepages = get_free_hugepages();
|
||||
if (free_hugepages < MIN_FREE_PAGES) {
|
||||
printf("Not enough free huge pages to test, exiting!\n");
|
||||
exit(KSFT_SKIP);
|
||||
}
|
||||
if (free_hugepages < MIN_FREE_PAGES)
|
||||
ksft_exit_skip("Not enough free huge pages (have %lu, need %d)\n", free_hugepages, MIN_FREE_PAGES);
|
||||
|
||||
fd = memfd_create(argv[0], MFD_HUGETLB);
|
||||
if (fd < 0) {
|
||||
perror("memfd_create() failed");
|
||||
exit(1);
|
||||
}
|
||||
if (fd < 0)
|
||||
ksft_exit_fail_perror("memfd_create");
|
||||
|
||||
/*
|
||||
* Test validity of MADV_DONTNEED addr and length arguments. mmap
|
||||
|
|
@ -90,16 +85,13 @@ int main(int argc, char **argv)
|
|||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
|
||||
-1, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
if (munmap(addr, huge_page_size) ||
|
||||
munmap(addr + (NR_HUGE_PAGES + 1) * huge_page_size,
|
||||
huge_page_size)) {
|
||||
perror("munmap");
|
||||
exit(1);
|
||||
}
|
||||
huge_page_size))
|
||||
ksft_exit_fail_perror("munmap");
|
||||
addr = addr + huge_page_size;
|
||||
|
||||
write_fault_pages(addr, NR_HUGE_PAGES);
|
||||
|
|
@ -108,20 +100,14 @@ int main(int argc, char **argv)
|
|||
/* addr before mapping should fail */
|
||||
ret = madvise(addr - base_page_size, NR_HUGE_PAGES * huge_page_size,
|
||||
MADV_DONTNEED);
|
||||
if (!ret) {
|
||||
printf("Unexpected success of madvise call with invalid addr line %d\n",
|
||||
__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
if (!ret)
|
||||
ksft_exit_fail_msg("madvise with invalid addr unexpectedly succeeded line %d\n", __LINE__);
|
||||
|
||||
/* addr + length after mapping should fail */
|
||||
ret = madvise(addr, (NR_HUGE_PAGES * huge_page_size) + base_page_size,
|
||||
MADV_DONTNEED);
|
||||
if (!ret) {
|
||||
printf("Unexpected success of madvise call with invalid length line %d\n",
|
||||
__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
if (!ret)
|
||||
ksft_exit_fail_msg("madvise with invalid length unexpectedly succeeded line %d\n", __LINE__);
|
||||
|
||||
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
|
||||
|
||||
|
|
@ -132,10 +118,9 @@ int main(int argc, char **argv)
|
|||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
|
||||
-1, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
write_fault_pages(addr, NR_HUGE_PAGES);
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
|
|
@ -143,19 +128,14 @@ int main(int argc, char **argv)
|
|||
ret = madvise(addr + base_page_size,
|
||||
NR_HUGE_PAGES * huge_page_size - base_page_size,
|
||||
MADV_DONTNEED);
|
||||
if (!ret) {
|
||||
printf("Unexpected success of madvise call with unaligned start address %d\n",
|
||||
__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
if (!ret)
|
||||
ksft_exit_fail_msg("madvise with unaligned start unexpectedly succeeded line %d\n", __LINE__);
|
||||
|
||||
/* addr + length should be aligned down to huge page size */
|
||||
if (madvise(addr,
|
||||
((NR_HUGE_PAGES - 1) * huge_page_size) + base_page_size,
|
||||
MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
/* should free all but last page in mapping */
|
||||
validate_free_pages(free_hugepages - 1);
|
||||
|
|
@ -170,17 +150,14 @@ int main(int argc, char **argv)
|
|||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
|
||||
-1, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
write_fault_pages(addr, NR_HUGE_PAGES);
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
/* should free all pages in mapping */
|
||||
validate_free_pages(free_hugepages);
|
||||
|
|
@ -190,29 +167,25 @@ int main(int argc, char **argv)
|
|||
/*
|
||||
* Test MADV_DONTNEED on private mapping of hugetlb file
|
||||
*/
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
|
||||
perror("fallocate");
|
||||
exit(1);
|
||||
}
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
|
||||
ksft_exit_fail_perror("fallocate");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
/* read should not consume any pages */
|
||||
read_fault_pages(addr, NR_HUGE_PAGES);
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/* madvise should not free any pages */
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/* writes should allocate private pages */
|
||||
|
|
@ -220,10 +193,9 @@ int main(int argc, char **argv)
|
|||
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
|
||||
|
||||
/* madvise should free private pages */
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/* writes should allocate private pages */
|
||||
|
|
@ -238,10 +210,9 @@ int main(int argc, char **argv)
|
|||
* implementation.
|
||||
*/
|
||||
if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||
0, NR_HUGE_PAGES * huge_page_size)) {
|
||||
perror("fallocate");
|
||||
exit(1);
|
||||
}
|
||||
0, NR_HUGE_PAGES * huge_page_size))
|
||||
ksft_exit_fail_perror("fallocate");
|
||||
|
||||
validate_free_pages(free_hugepages);
|
||||
|
||||
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
|
||||
|
|
@ -249,29 +220,25 @@ int main(int argc, char **argv)
|
|||
/*
|
||||
* Test MADV_DONTNEED on shared mapping of hugetlb file
|
||||
*/
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
|
||||
perror("fallocate");
|
||||
exit(1);
|
||||
}
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
|
||||
ksft_exit_fail_perror("fallocate");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
/* write should not consume any pages */
|
||||
write_fault_pages(addr, NR_HUGE_PAGES);
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/* madvise should not free any pages */
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/*
|
||||
|
|
@ -279,29 +246,25 @@ int main(int argc, char **argv)
|
|||
*
|
||||
* madvise is same as hole punch and should free all pages.
|
||||
*/
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages);
|
||||
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
|
||||
|
||||
/*
|
||||
* Test MADV_REMOVE on shared and private mapping of hugetlb file
|
||||
*/
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size)) {
|
||||
perror("fallocate");
|
||||
exit(1);
|
||||
}
|
||||
if (fallocate(fd, 0, 0, NR_HUGE_PAGES * huge_page_size))
|
||||
ksft_exit_fail_perror("fallocate");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
addr = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
/* shared write should not consume any additional pages */
|
||||
write_fault_pages(addr, NR_HUGE_PAGES);
|
||||
|
|
@ -310,10 +273,8 @@ int main(int argc, char **argv)
|
|||
addr2 = mmap(NULL, NR_HUGE_PAGES * huge_page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE, fd, 0);
|
||||
if (addr2 == MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(1);
|
||||
}
|
||||
if (addr2 == MAP_FAILED)
|
||||
ksft_exit_fail_perror("mmap");
|
||||
|
||||
/* private read should not consume any pages */
|
||||
read_fault_pages(addr2, NR_HUGE_PAGES);
|
||||
|
|
@ -324,17 +285,15 @@ int main(int argc, char **argv)
|
|||
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
|
||||
|
||||
/* madvise of shared mapping should not free any pages */
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages - (2 * NR_HUGE_PAGES));
|
||||
|
||||
/* madvise of private mapping should free private pages */
|
||||
if (madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr2, NR_HUGE_PAGES * huge_page_size, MADV_DONTNEED))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages - NR_HUGE_PAGES);
|
||||
|
||||
/* private write should consume additional pages again */
|
||||
|
|
@ -346,15 +305,16 @@ int main(int argc, char **argv)
|
|||
* not correct. private pages should not be freed, but this is
|
||||
* expected. See comment associated with FALLOC_FL_PUNCH_HOLE call.
|
||||
*/
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE)) {
|
||||
perror("madvise");
|
||||
exit(1);
|
||||
}
|
||||
if (madvise(addr, NR_HUGE_PAGES * huge_page_size, MADV_REMOVE))
|
||||
ksft_exit_fail_perror("madvise");
|
||||
|
||||
validate_free_pages(free_hugepages);
|
||||
|
||||
(void)munmap(addr, NR_HUGE_PAGES * huge_page_size);
|
||||
(void)munmap(addr2, NR_HUGE_PAGES * huge_page_size);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
|
||||
ksft_test_result_pass("MADV_DONTNEED and MADV_REMOVE on hugetlb\n");
|
||||
ksft_finished();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user