Re: [PATCH 09/53] selftests/mm: hugetlb-madvise: use kselftest framework

Donet Tom
2026-04-09T16:56:24Z

On 4/6/26 7:46 PM, Mike Rapoport wrote:
> From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
>
> Convert hugetlb-madvise test to use kselftest framework for reporting
> and tracking successful and failing runs.
>
> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
> ---
> tools/testing/selftests/mm/hugetlb-madvise.c | 204 ++++++++-----------
> 1 file changed, 82 insertions(+), 122 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
> index 898cc90b314f..4c6c346a3af5 100644
> --- a/tools/testing/selftests/mm/hugetlb-madvise.c
> +++ b/tools/testing/selftests/mm/hugetlb-madvise.c
> @@ -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 %ld, expected %ld 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();
> }
LGTM

Reviewed by: Donet Tom <donettom@linux.ibm.com>

-Donet