In ksm_functional_tests, test_child_ksm() returned negative values
to indicate errors. However, when passed to exit(), these were
interpreted as large unsigned values (e.g, -2 became 254), leading to
incorrect handling in the parent process. As a result, some tests
appeared to be skipped or silently failed.
This patch changes test_child_ksm() to return positive error codes
(1, 2, 3) and updates test_child_ksm_err() to interpret them correctly.
This ensures the parent accurately detects and reports child process
failures.
--------------
Before patch:
--------------
- [RUN] test_unmerge
ok 1 Pages were unmerged
...
- [RUN] test_prctl_fork
- No pages got merged
- [RUN] test_prctl_fork_exec
ok 7 PR_SET_MEMORY_MERGE value is inherited
...
Bail out! 1 out of 8 tests failed
- Planned tests != run tests (9 != 8)
- Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0
--------------
After patch:
--------------
- [RUN] test_unmerge
ok 1 Pages were unmerged
...
- [RUN] test_prctl_fork
- No pages got merged
not ok 7 Merge in child failed
- [RUN] test_prctl_fork_exec
ok 8 PR_SET_MEMORY_MERGE value is inherited
...
Bail out! 2 out of 9 tests failed
- Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0
Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec")
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
---
tools/testing/selftests/mm/ksm_functional_tests.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c
index 996dc6645570..b080d591d984 100644
--- a/tools/testing/selftests/mm/ksm_functional_tests.c
+++ b/tools/testing/selftests/mm/ksm_functional_tests.c
@@ -512,14 +512,14 @@ static int test_child_ksm(void)
/* Test if KSM is enabled for the process. */
if (prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) != 1)
- return -1;
+ return 1;
/* Test if merge could really happen. */
map = __mmap_and_merge_range(0xcf, size, PROT_READ | PROT_WRITE, KSM_MERGE_NONE);
if (map == MAP_MERGE_FAIL)
- return -2;
+ return 2;
else if (map == MAP_MERGE_SKIP)
- return -3;
+ return 3;
ksm_unmerge();
munmap(map, size);
@@ -528,11 +528,11 @@ static int test_child_ksm(void)
static void test_child_ksm_err(int status)
{
- if (status == -1)
+ if (status == 1)
ksft_test_result_fail("unexpected PR_GET_MEMORY_MERGE result in child\n");
- else if (status == -2)
+ else if (status == 2)
ksft_test_result_fail("Merge in child failed\n");
- else if (status == -3)
+ else if (status == 3)
ksft_test_result_skip("Merge in child skipped\n");
}
--
2.43.5
On 03.07.25 08:06, Aboorva Devarajan wrote: > In ksm_functional_tests, test_child_ksm() returned negative values > to indicate errors. However, when passed to exit(), these were > interpreted as large unsigned values (e.g, -2 became 254), leading to > incorrect handling in the parent process. As a result, some tests > appeared to be skipped or silently failed. > > This patch changes test_child_ksm() to return positive error codes > (1, 2, 3) and updates test_child_ksm_err() to interpret them correctly. > This ensures the parent accurately detects and reports child process > failures. > > -------------- > Before patch: > -------------- > - [RUN] test_unmerge > ok 1 Pages were unmerged > ... > - [RUN] test_prctl_fork > - No pages got merged > - [RUN] test_prctl_fork_exec > ok 7 PR_SET_MEMORY_MERGE value is inherited > ... > Bail out! 1 out of 8 tests failed > - Planned tests != run tests (9 != 8) > - Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0 > > -------------- > After patch: > -------------- > - [RUN] test_unmerge > ok 1 Pages were unmerged > ... > - [RUN] test_prctl_fork > - No pages got merged > not ok 7 Merge in child failed > - [RUN] test_prctl_fork_exec > ok 8 PR_SET_MEMORY_MERGE value is inherited > ... > Bail out! 2 out of 9 tests failed > - Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0 > > Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec") > Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> BTW, when I run the test, I get this weird output TAP version 13 1..9 # [RUN] test_unmerge ok 1 Pages were unmerged # [RUN] test_unmerge_zero_pages ok 2 KSM zero pages were unmerged # [RUN] test_unmerge_discarded ok 3 Pages were unmerged # [RUN] test_unmerge_uffd_wp ok 4 Pages were unmerged # [RUN] test_prot_none ok 5 Pages were unmerged # [RUN] test_prctl ok 6 Setting/clearing PR_SET_MEMORY_MERGE works # [RUN] test_prctl_fork ok 7 PR_SET_MEMORY_MERGE value is inherited # [RUN] test_prctl_fork_exec ^ where is the test? # [RUN] test_prctl_unmerge ok 8 Pages were unmerged # Planned tests != run tests (9 != 8) # Totals: pass:8 fail:0 xfail:0 xpass:0 skip:0 error:0 ^ what? ok 8 PR_SET_MEMORY_MERGE value is inherited # [RUN] test_prctl_unmerge ok 9 Pages were unmerged # Totals: pass:9 fail:0 xfail:0 xpass:0 skip:0 error:0 ^ huh, what now? -- Cheers, David / dhildenb
Hi David On 7/3/25 2:03 PM, David Hildenbrand wrote: > On 03.07.25 08:06, Aboorva Devarajan wrote: >> In ksm_functional_tests, test_child_ksm() returned negative values >> to indicate errors. However, when passed to exit(), these were >> interpreted as large unsigned values (e.g, -2 became 254), leading to >> incorrect handling in the parent process. As a result, some tests >> appeared to be skipped or silently failed. >> >> This patch changes test_child_ksm() to return positive error codes >> (1, 2, 3) and updates test_child_ksm_err() to interpret them correctly. >> This ensures the parent accurately detects and reports child process >> failures. >> >> -------------- >> Before patch: >> -------------- >> - [RUN] test_unmerge >> ok 1 Pages were unmerged >> ... >> - [RUN] test_prctl_fork >> - No pages got merged >> - [RUN] test_prctl_fork_exec >> ok 7 PR_SET_MEMORY_MERGE value is inherited >> ... >> Bail out! 1 out of 8 tests failed >> - Planned tests != run tests (9 != 8) >> - Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0 >> >> -------------- >> After patch: >> -------------- >> - [RUN] test_unmerge >> ok 1 Pages were unmerged >> ... >> - [RUN] test_prctl_fork >> - No pages got merged >> not ok 7 Merge in child failed >> - [RUN] test_prctl_fork_exec >> ok 8 PR_SET_MEMORY_MERGE value is inherited >> ... >> Bail out! 2 out of 9 tests failed >> - Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0 >> >> Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test >> case for ksm fork/exec") >> Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> > > BTW, when I run the test, I get this weird output > > TAP version 13 > 1..9 > # [RUN] test_unmerge > ok 1 Pages were unmerged > # [RUN] test_unmerge_zero_pages > ok 2 KSM zero pages were unmerged > # [RUN] test_unmerge_discarded > ok 3 Pages were unmerged > # [RUN] test_unmerge_uffd_wp > ok 4 Pages were unmerged > # [RUN] test_prot_none > ok 5 Pages were unmerged > # [RUN] test_prctl > ok 6 Setting/clearing PR_SET_MEMORY_MERGE works > # [RUN] test_prctl_fork > ok 7 PR_SET_MEMORY_MERGE value is inherited > # [RUN] test_prctl_fork_exec > > ^ where is the test? > > # [RUN] test_prctl_unmerge > ok 8 Pages were unmerged > # Planned tests != run tests (9 != 8) > # Totals: pass:8 fail:0 xfail:0 xpass:0 skip:0 error:0 > > ^ what? > > ok 8 PR_SET_MEMORY_MERGE value is inherited > # [RUN] test_prctl_unmerge > ok 9 Pages were unmerged > # Totals: pass:9 fail:0 xfail:0 xpass:0 skip:0 error:0 > > ^ huh, what now? > The problem with the exec test is that it uses its own binary to exec. } else if (child_pid == 0) { char *prg_name = "./ksm_functional_tests"; char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME, NULL }; execv(prg_name, argv_for_program); return; } So we should run it on the same directory where the binary present.
On 03.07.25 10:51, Donet Tom wrote: > Hi David > > On 7/3/25 2:03 PM, David Hildenbrand wrote: >> On 03.07.25 08:06, Aboorva Devarajan wrote: >>> In ksm_functional_tests, test_child_ksm() returned negative values >>> to indicate errors. However, when passed to exit(), these were >>> interpreted as large unsigned values (e.g, -2 became 254), leading to >>> incorrect handling in the parent process. As a result, some tests >>> appeared to be skipped or silently failed. >>> >>> This patch changes test_child_ksm() to return positive error codes >>> (1, 2, 3) and updates test_child_ksm_err() to interpret them correctly. >>> This ensures the parent accurately detects and reports child process >>> failures. >>> >>> -------------- >>> Before patch: >>> -------------- >>> - [RUN] test_unmerge >>> ok 1 Pages were unmerged >>> ... >>> - [RUN] test_prctl_fork >>> - No pages got merged >>> - [RUN] test_prctl_fork_exec >>> ok 7 PR_SET_MEMORY_MERGE value is inherited >>> ... >>> Bail out! 1 out of 8 tests failed >>> - Planned tests != run tests (9 != 8) >>> - Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0 >>> >>> -------------- >>> After patch: >>> -------------- >>> - [RUN] test_unmerge >>> ok 1 Pages were unmerged >>> ... >>> - [RUN] test_prctl_fork >>> - No pages got merged >>> not ok 7 Merge in child failed >>> - [RUN] test_prctl_fork_exec >>> ok 8 PR_SET_MEMORY_MERGE value is inherited >>> ... >>> Bail out! 2 out of 9 tests failed >>> - Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0 >>> >>> Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test >>> case for ksm fork/exec") >>> Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> >> >> BTW, when I run the test, I get this weird output >> >> TAP version 13 >> 1..9 >> # [RUN] test_unmerge >> ok 1 Pages were unmerged >> # [RUN] test_unmerge_zero_pages >> ok 2 KSM zero pages were unmerged >> # [RUN] test_unmerge_discarded >> ok 3 Pages were unmerged >> # [RUN] test_unmerge_uffd_wp >> ok 4 Pages were unmerged >> # [RUN] test_prot_none >> ok 5 Pages were unmerged >> # [RUN] test_prctl >> ok 6 Setting/clearing PR_SET_MEMORY_MERGE works >> # [RUN] test_prctl_fork >> ok 7 PR_SET_MEMORY_MERGE value is inherited >> # [RUN] test_prctl_fork_exec >> >> ^ where is the test? >> >> # [RUN] test_prctl_unmerge >> ok 8 Pages were unmerged >> # Planned tests != run tests (9 != 8) >> # Totals: pass:8 fail:0 xfail:0 xpass:0 skip:0 error:0 >> >> ^ what? >> >> ok 8 PR_SET_MEMORY_MERGE value is inherited >> # [RUN] test_prctl_unmerge >> ok 9 Pages were unmerged >> # Totals: pass:9 fail:0 xfail:0 xpass:0 skip:0 error:0 >> >> ^ huh, what now? >> > > The problem with the exec test is that it uses its own binary to exec. > > } else if (child_pid == 0) { > char *prg_name = "./ksm_functional_tests"; > char *argv_for_program[] = { prg_name, > FORK_EXEC_CHILD_PRG_NAME, NULL }; > > execv(prg_name, argv_for_program); > return; > } > > So we should run it on the same directory where the binary present. So, I assume the execv fails. We should handle that, and figure out why it fails. diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c index d8bd1911dfc0a..0ddbb390df33b 100644 --- a/tools/testing/selftests/mm/ksm_functional_tests.c +++ b/tools/testing/selftests/mm/ksm_functional_tests.c @@ -527,6 +527,8 @@ static void test_child_ksm_err(int status) ksft_test_result_fail("Merge in child failed\n"); else if (status == -3) ksft_test_result_skip("Merge in child skipped\n"); + else if (status == 4) + ksft_test_result_fail("Binary not found\n"); } /* Verify that prctl ksm flag is inherited. */ @@ -598,7 +600,7 @@ static void test_prctl_fork_exec(void) char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME }; execv(prg_name, argv_for_program); - return; + exit(4); } if (waitpid(child_pid, &status, 0) > 0) { results in TAP version 13 1..9 # [RUN] test_unmerge ok 1 Pages were unmerged # [RUN] test_unmerge_zero_pages ok 2 KSM zero pages were unmerged # [RUN] test_unmerge_discarded ok 3 Pages were unmerged # [RUN] test_unmerge_uffd_wp ok 4 Pages were unmerged # [RUN] test_prot_none ok 5 Pages were unmerged # [RUN] test_prctl ok 6 Setting/clearing PR_SET_MEMORY_MERGE works # [RUN] test_prctl_fork ok 7 PR_SET_MEMORY_MERGE value is inherited # [RUN] test_prctl_fork_exec not ok 8 Binary not found # [RUN] test_prctl_unmerge ok 9 Pages were unmerged Bail out! 1 out of 9 tests failed # Totals: pass:8 fail:1 xfail:0 xpass:0 skip:0 error:0 -- Cheers, David / dhildenb
On 7/3/25 2:44 PM, David Hildenbrand wrote: > On 03.07.25 10:51, Donet Tom wrote: >> Hi David >> >> On 7/3/25 2:03 PM, David Hildenbrand wrote: >>> On 03.07.25 08:06, Aboorva Devarajan wrote: >>>> In ksm_functional_tests, test_child_ksm() returned negative values >>>> to indicate errors. However, when passed to exit(), these were >>>> interpreted as large unsigned values (e.g, -2 became 254), leading to >>>> incorrect handling in the parent process. As a result, some tests >>>> appeared to be skipped or silently failed. >>>> >>>> This patch changes test_child_ksm() to return positive error codes >>>> (1, 2, 3) and updates test_child_ksm_err() to interpret them >>>> correctly. >>>> This ensures the parent accurately detects and reports child process >>>> failures. >>>> >>>> -------------- >>>> Before patch: >>>> -------------- >>>> - [RUN] test_unmerge >>>> ok 1 Pages were unmerged >>>> ... >>>> - [RUN] test_prctl_fork >>>> - No pages got merged >>>> - [RUN] test_prctl_fork_exec >>>> ok 7 PR_SET_MEMORY_MERGE value is inherited >>>> ... >>>> Bail out! 1 out of 8 tests failed >>>> - Planned tests != run tests (9 != 8) >>>> - Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0 >>>> >>>> -------------- >>>> After patch: >>>> -------------- >>>> - [RUN] test_unmerge >>>> ok 1 Pages were unmerged >>>> ... >>>> - [RUN] test_prctl_fork >>>> - No pages got merged >>>> not ok 7 Merge in child failed >>>> - [RUN] test_prctl_fork_exec >>>> ok 8 PR_SET_MEMORY_MERGE value is inherited >>>> ... >>>> Bail out! 2 out of 9 tests failed >>>> - Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0 >>>> >>>> Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test >>>> case for ksm fork/exec") >>>> Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> >>> >>> BTW, when I run the test, I get this weird output >>> >>> TAP version 13 >>> 1..9 >>> # [RUN] test_unmerge >>> ok 1 Pages were unmerged >>> # [RUN] test_unmerge_zero_pages >>> ok 2 KSM zero pages were unmerged >>> # [RUN] test_unmerge_discarded >>> ok 3 Pages were unmerged >>> # [RUN] test_unmerge_uffd_wp >>> ok 4 Pages were unmerged >>> # [RUN] test_prot_none >>> ok 5 Pages were unmerged >>> # [RUN] test_prctl >>> ok 6 Setting/clearing PR_SET_MEMORY_MERGE works >>> # [RUN] test_prctl_fork >>> ok 7 PR_SET_MEMORY_MERGE value is inherited >>> # [RUN] test_prctl_fork_exec >>> >>> ^ where is the test? >>> >>> # [RUN] test_prctl_unmerge >>> ok 8 Pages were unmerged >>> # Planned tests != run tests (9 != 8) >>> # Totals: pass:8 fail:0 xfail:0 xpass:0 skip:0 error:0 >>> >>> ^ what? >>> >>> ok 8 PR_SET_MEMORY_MERGE value is inherited >>> # [RUN] test_prctl_unmerge >>> ok 9 Pages were unmerged >>> # Totals: pass:9 fail:0 xfail:0 xpass:0 skip:0 error:0 >>> >>> ^ huh, what now? >>> >> >> The problem with the exec test is that it uses its own binary to exec. >> >> } else if (child_pid == 0) { >> char *prg_name = "./ksm_functional_tests"; >> char *argv_for_program[] = { prg_name, >> FORK_EXEC_CHILD_PRG_NAME, NULL }; >> >> execv(prg_name, argv_for_program); >> return; >> } > > > So we should run it on the same directory where the binary present. > > So, I assume the execv fails. We should handle that, and figure out > why it fails. > > diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c > b/tools/testing/selftests/mm/ksm_functional_tests.c > index d8bd1911dfc0a..0ddbb390df33b 100644 > --- a/tools/testing/selftests/mm/ksm_functional_tests.c > +++ b/tools/testing/selftests/mm/ksm_functional_tests.c > @@ -527,6 +527,8 @@ static void test_child_ksm_err(int status) > ksft_test_result_fail("Merge in child failed\n"); > else if (status == -3) > ksft_test_result_skip("Merge in child skipped\n"); > + else if (status == 4) > + ksft_test_result_fail("Binary not found\n"); > } > > /* Verify that prctl ksm flag is inherited. */ > @@ -598,7 +600,7 @@ static void test_prctl_fork_exec(void) > char *argv_for_program[] = { prg_name, > FORK_EXEC_CHILD_PRG_NAME }; > > execv(prg_name, argv_for_program); > - return; > + exit(4); > } > > if (waitpid(child_pid, &status, 0) > 0) { > > results in > > TAP version 13 > 1..9 > # [RUN] test_unmerge > ok 1 Pages were unmerged > # [RUN] test_unmerge_zero_pages > ok 2 KSM zero pages were unmerged > # [RUN] test_unmerge_discarded > ok 3 Pages were unmerged > # [RUN] test_unmerge_uffd_wp > ok 4 Pages were unmerged > # [RUN] test_prot_none > ok 5 Pages were unmerged > # [RUN] test_prctl > ok 6 Setting/clearing PR_SET_MEMORY_MERGE works > # [RUN] test_prctl_fork > ok 7 PR_SET_MEMORY_MERGE value is inherited > # [RUN] test_prctl_fork_exec > not ok 8 Binary not found > # [RUN] test_prctl_unmerge > ok 9 Pages were unmerged > Bail out! 1 out of 9 tests failed > # Totals: pass:8 fail:1 xfail:0 xpass:0 skip:0 error:0 Thanks David. We will add this in next version. > >
On 03.07.25 08:06, Aboorva Devarajan wrote: > In ksm_functional_tests, test_child_ksm() returned negative values > to indicate errors. However, when passed to exit(), these were > interpreted as large unsigned values (e.g, -2 became 254), leading to > incorrect handling in the parent process. As a result, some tests > appeared to be skipped or silently failed. > > This patch changes test_child_ksm() to return positive error codes > (1, 2, 3) and updates test_child_ksm_err() to interpret them correctly. > This ensures the parent accurately detects and reports child process > failures. > > -------------- > Before patch: > -------------- > - [RUN] test_unmerge > ok 1 Pages were unmerged > ... > - [RUN] test_prctl_fork > - No pages got merged > - [RUN] test_prctl_fork_exec > ok 7 PR_SET_MEMORY_MERGE value is inherited > ... > Bail out! 1 out of 8 tests failed > - Planned tests != run tests (9 != 8) > - Totals: pass:7 fail:1 xfail:0 xpass:0 skip:0 error:0 > > -------------- > After patch: > -------------- > - [RUN] test_unmerge > ok 1 Pages were unmerged > ... > - [RUN] test_prctl_fork > - No pages got merged > not ok 7 Merge in child failed > - [RUN] test_prctl_fork_exec > ok 8 PR_SET_MEMORY_MERGE value is inherited > ... > Bail out! 2 out of 9 tests failed > - Totals: pass:7 fail:2 xfail:0 xpass:0 skip:0 error:0 > > Fixes: 6c47de3be3a0 ("selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec") > Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com> Surprising, but seems to be the right thing to do. Acked-by: David Hildenbrand <david@redhat.com> -- Cheers, David / dhildenb
© 2016 - 2025 Red Hat, Inc.