]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
selftest/mm: fix ksm_funtional_test failures
authorDonet Tom <donettom@linux.ibm.com>
Sat, 16 Aug 2025 04:01:09 +0000 (09:31 +0530)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 12 Sep 2025 00:25:01 +0000 (17:25 -0700)
This patch fixes 2 issues.

1) After fork() in test_prctl_fork, the child process uses the file
   descriptors from the parent process to read ksm_stat and
   ksm_merging_pages.  This results in incorrect values being read (parent
   process ksm_stat and ksm_merging_pages will be read in child), causing
   the test to fail.

   This patch calls init_global_file_handles() in the child process to
   ensure that the current process's file descriptors are used to read
   ksm_stat and ksm_merging_pages.

2) All tests currently call ksm_merge to trigger page merging.  To
   ensure the system remains in a consistent state for subsequent tests,
   it is better to call ksm_unmerge during the test cleanup phase

   In the test_prctl_fork test, after a fork(), reading
   ksm_merging_pages in the child process returns a non-zero value because
   a previous test performed a merge, and the child's memory state is
   inherited from the parent.

   Although the child process calls ksm_unmerge, the ksm_merging_pages
   counter in the parent is reset to zero, while the child's counter
   remains unchanged.  This discrepancy causes the test to fail.

   To avoid this issue, each test should call ksm_unmerge during
   cleanup to ensure the counter is reset and the system is in a clean
   state for subsequent tests.

execv argument is an array of pointers to null-terminated strings.  In
this patch we also added NULL in the execv argument.

Link: https://lkml.kernel.org/r/20250816040113.760010-4-aboorvad@linux.ibm.com
Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec")
Co-developed-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Signed-off-by: Donet Tom <donettom@linux.ibm.com>
Reviewed-by: Wei Yang <richard.weiyang@gmail.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mariano Pache <npache@redhat.com>
Cc: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
tools/testing/selftests/mm/ksm_functional_tests.c

index d8bd1911dfc0a27ff1221d357f70a8852f559285..996dc6645570d3878917b6054b0c4534cbc5f40e 100644 (file)
@@ -46,6 +46,8 @@ static int ksm_use_zero_pages_fd;
 static int pagemap_fd;
 static size_t pagesize;
 
+static void init_global_file_handles(void);
+
 static bool range_maps_duplicates(char *addr, unsigned long size)
 {
        unsigned long offs_a, offs_b, pfn_a, pfn_b;
@@ -274,6 +276,7 @@ static void test_unmerge(void)
        ksft_test_result(!range_maps_duplicates(map, size),
                         "Pages were unmerged\n");
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }
 
@@ -338,6 +341,7 @@ static void test_unmerge_zero_pages(void)
        ksft_test_result(!range_maps_duplicates(map, size),
                        "KSM zero pages were unmerged\n");
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }
 
@@ -366,6 +370,7 @@ static void test_unmerge_discarded(void)
        ksft_test_result(!range_maps_duplicates(map, size),
                         "Pages were unmerged\n");
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }
 
@@ -452,6 +457,7 @@ static void test_unmerge_uffd_wp(void)
 close_uffd:
        close(uffd);
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }
 #endif
@@ -515,6 +521,7 @@ static int test_child_ksm(void)
        else if (map == MAP_MERGE_SKIP)
                return -3;
 
+       ksm_unmerge();
        munmap(map, size);
        return 0;
 }
@@ -548,6 +555,7 @@ static void test_prctl_fork(void)
 
        child_pid = fork();
        if (!child_pid) {
+               init_global_file_handles();
                exit(test_child_ksm());
        } else if (child_pid < 0) {
                ksft_test_result_fail("fork() failed\n");
@@ -595,7 +603,7 @@ static void test_prctl_fork_exec(void)
                return;
        } else if (child_pid == 0) {
                char *prg_name = "./ksm_functional_tests";
-               char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME };
+               char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME, NULL };
 
                execv(prg_name, argv_for_program);
                return;
@@ -644,6 +652,7 @@ static void test_prctl_unmerge(void)
        ksft_test_result(!range_maps_duplicates(map, size),
                         "Pages were unmerged\n");
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }
 
@@ -677,6 +686,7 @@ static void test_prot_none(void)
        ksft_test_result(!range_maps_duplicates(map, size),
                         "Pages were unmerged\n");
 unmap:
+       ksm_unmerge();
        munmap(map, size);
 }