]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/testing/selftests: test MREMAP_DONTUNMAP on multiple VMA move
authorLorenzo Stoakes <lorenzo.stoakes@oracle.com>
Mon, 21 Jul 2025 17:33:26 +0000 (18:33 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 25 Jul 2025 02:12:42 +0000 (19:12 -0700)
We support MREMAP_MAYMOVE | MREMAP_FIXED | MREMAP_DONTUNMAP for moving
multiple VMAs via mremap(), so assert that the tests pass with both
MREMAP_DONTUNMAP set and not set.

Additionally, add success = false settings when mremap() fails.  This is
something that cannot realistically happen, so in no way impacted test
outcome, but it is incorrect to indicate a test pass when something has
failed.

Link: https://lkml.kernel.org/r/d7359941981e4e44c774753b3e364d1c54928e6a.1753119043.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Jann Horn <jannh@google.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
tools/testing/selftests/mm/mremap_test.c

index 141a9032414e275db8674631a8dd855101eac1c5..d3b4772cd8c9d3e1004fac2acdc63f75d6fe19e6 100644 (file)
@@ -406,14 +406,19 @@ static bool is_multiple_vma_range_ok(unsigned int pattern_seed,
 }
 
 static void mremap_move_multiple_vmas(unsigned int pattern_seed,
-                                     unsigned long page_size)
+                                     unsigned long page_size,
+                                     bool dont_unmap)
 {
+       int mremap_flags = MREMAP_FIXED | MREMAP_MAYMOVE;
        char *test_name = "mremap move multiple vmas";
        const size_t size = 11 * page_size;
        bool success = true;
        char *ptr, *tgt_ptr;
        int i;
 
+       if (dont_unmap)
+               mremap_flags |= MREMAP_DONTUNMAP;
+
        ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
                   MAP_PRIVATE | MAP_ANON, -1, 0);
        if (ptr == MAP_FAILED) {
@@ -467,8 +472,7 @@ static void mremap_move_multiple_vmas(unsigned int pattern_seed,
        }
 
        /* First, just move the whole thing. */
-       if (mremap(ptr, size, size,
-                  MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr) == MAP_FAILED) {
+       if (mremap(ptr, size, size, mremap_flags, tgt_ptr) == MAP_FAILED) {
                perror("mremap");
                success = false;
                goto out_unmap;
@@ -480,9 +484,10 @@ static void mremap_move_multiple_vmas(unsigned int pattern_seed,
        }
 
        /* Move next to itself. */
-       if (mremap(tgt_ptr, size, size,
-                  MREMAP_MAYMOVE | MREMAP_FIXED, &tgt_ptr[size]) == MAP_FAILED) {
+       if (mremap(tgt_ptr, size, size, mremap_flags,
+                  &tgt_ptr[size]) == MAP_FAILED) {
                perror("mremap");
+               success = false;
                goto out_unmap;
        }
        /* Check that the move is ok. */
@@ -500,8 +505,9 @@ static void mremap_move_multiple_vmas(unsigned int pattern_seed,
        }
        /* Move and overwrite. */
        if (mremap(&tgt_ptr[size], size, size,
-                  MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr) == MAP_FAILED) {
+                  mremap_flags, tgt_ptr) == MAP_FAILED) {
                perror("mremap");
+               success = false;
                goto out_unmap;
        }
        /* Check that the move is ok. */
@@ -518,9 +524,11 @@ out_unmap:
 
 out:
        if (success)
-               ksft_test_result_pass("%s\n", test_name);
+               ksft_test_result_pass("%s%s\n", test_name,
+                                     dont_unmap ? " [dontunnmap]" : "");
        else
-               ksft_test_result_fail("%s\n", test_name);
+               ksft_test_result_fail("%s%s\n", test_name,
+                                     dont_unmap ? " [dontunnmap]" : "");
 }
 
 static void mremap_shrink_multiple_vmas(unsigned long page_size,
@@ -943,7 +951,7 @@ int main(int argc, char **argv)
        char *rand_addr;
        size_t rand_size;
        int num_expand_tests = 2;
-       int num_misc_tests = 5;
+       int num_misc_tests = 6;
        struct test test_cases[MAX_TEST] = {};
        struct test perf_test_cases[MAX_PERF_TEST];
        int page_size;
@@ -1070,9 +1078,10 @@ int main(int argc, char **argv)
 
        mremap_move_within_range(pattern_seed, rand_addr);
        mremap_move_1mb_from_start(pattern_seed, rand_addr);
-       mremap_move_multiple_vmas(pattern_seed, page_size);
        mremap_shrink_multiple_vmas(page_size, /* inplace= */true);
        mremap_shrink_multiple_vmas(page_size, /* inplace= */false);
+       mremap_move_multiple_vmas(pattern_seed, page_size, /* dontunmap= */ false);
+       mremap_move_multiple_vmas(pattern_seed, page_size, /* dontunmap= */ true);
 
        if (run_perf_tests) {
                ksft_print_msg("\n%s\n",