From: David Hildenbrand <david@redhat.com>
To: Jinjiang Tu <tujinjiang@huawei.com>,
akpm@linux-foundation.org, shr@devkernel.io, hannes@cmpxchg.org,
riel@surriel.com, wangkefeng.wang@huawei.com,
sunnanyong@huawei.com, linux-mm@kvack.org
Subject: Re: [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
Date: Fri, 22 Mar 2024 12:43:57 +0100 [thread overview]
Message-ID: <bf346a9e-32d5-449a-b81e-dc480c2e89d4@redhat.com> (raw)
In-Reply-To: <20240322060947.3254967-3-tujinjiang@huawei.com>
On 22.03.24 07:09, Jinjiang Tu wrote:
> This extends test_prctl_fork() and test_prctl_fork_exec() to make sure
> that deduplication really happens, instead of only test the
> MMF_VM_MERGE_ANY flag is set.
>
> Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
> ---
> .../selftests/mm/ksm_functional_tests.c | 79 +++++++++++++++++--
> 1 file changed, 73 insertions(+), 6 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c
> index d615767e396b..01999aab2e37 100644
> --- a/tools/testing/selftests/mm/ksm_functional_tests.c
> +++ b/tools/testing/selftests/mm/ksm_functional_tests.c
> @@ -146,6 +146,54 @@ static int ksm_unmerge(void)
> return 0;
> }
>
> +static int child_test_merge(void)
> +{
> + const unsigned int size = 2 * MiB;
> + char *map;
> + int ret = -1;
> +
> + /* Stabilize accounting by disabling KSM completely. */
> + if (ksm_unmerge()) {
> + ksft_print_msg("Disabling (unmerging) KSM failed\n");
> + return ret;
> + }
> +
> + if (get_my_merging_pages() > 0) {
> + ksft_print_msg("Still pages merged\n");
> + return ret;
> + }
> +
> + map = mmap(NULL, size, PROT_READ|PROT_WRITE,
> + MAP_PRIVATE|MAP_ANON, -1, 0);
> + if (map == MAP_FAILED) {
> + ksft_print_msg("mmap() failed\n");
> + return ret;
> + }
> +
> + /* Don't use THP. Ignore if THP are not around on a kernel. */
> + if (madvise(map, size, MADV_NOHUGEPAGE) && errno != EINVAL) {
> + ksft_print_msg("MADV_NOHUGEPAGE failed\n");
> + goto unmap;
> + }
> +
> + memset(map, 0x1c, size);
> +
> + if (ksm_merge()) {
> + ksft_print_msg("Running KSM failed\n");
> + goto unmap;
> + }
> +
> + if (get_my_merging_pages() <= 0) {
> + ksft_print_msg("Fail to merge\n");
> + goto unmap;
> + }
Looks like all you want is use mmap_and_merge_range(), but neither
setting the prctl nor madvise().
Two alternatives:
1) switching from "bool use_prctl" to an enum like
enum ksm_merge_mode {
KSM_MERGE_PRCTL
KSM_MERGE_MADVISE,
KSM_MERGE_NONE, /* PRCTL already set */
};
Then, you can simply use mmap_and_merge_range(0x1c, 2 * MiB,
PROT_READ|PROT_WRITE, KSM_MERGE_NONE);
2) With "bool use_prctl", before doing the prctl(PR_SET_MEMORY_MERGE,
...), check if it is already enabled.
As we do that already in ksm_fork_exec_child(), and fail if it isn't
set, that should work.
Then, you can simply use mmap_and_merge_range(0x1c, 2 * MiB,
PROT_READ|PROT_WRITE, true);
here.
> +
> + ret = 0;
> +unmap:
> + munmap(map, size);
> + return ret;
> +}
> +
> static char *mmap_and_merge_range(char val, unsigned long size, int prot,
> bool use_prctl)
> {
> @@ -458,7 +506,11 @@ static void test_prctl_fork(void)
>
> child_pid = fork();
> if (!child_pid) {
> - exit(prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0));
> + if (prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) != 1)
> + exit(-1);
> + if (child_test_merge() != 0)
> + exit(-2);
> + exit(0);
> } else if (child_pid < 0) {
> ksft_test_result_fail("fork() failed\n");
> return;
> @@ -467,8 +519,14 @@ static void test_prctl_fork(void)
> if (waitpid(child_pid, &status, 0) < 0) {
> ksft_test_result_fail("waitpid() failed\n");
> return;
> - } else if (WEXITSTATUS(status) != 1) {
> - ksft_test_result_fail("unexpected PR_GET_MEMORY_MERGE result in child\n");
> + }
> +
> + status = WEXITSTATUS(status);
> + if (status != 0) {
> + if (status == -1)
> + ksft_test_result_fail("unexpected PR_GET_MEMORY_MERGE result in child\n");
> + else
> + ksft_test_result_fail("fail to merge in child\n");
> return;
> }
>
> @@ -483,7 +541,13 @@ static void test_prctl_fork(void)
> static int ksm_fork_exec_child(void)
> {
> /* Test if KSM is enabled for the process. */
> - return prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) == 1;
> + if (prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) != 1)
> + return -1;
> +
> + if (child_test_merge() != 0)
You can drop the "!=0". But maybe, you can just inline the call to
mmap_and_merge_range() here.
> + return -2;
> +
> + return 0;
--
Cheers,
David / dhildenb
next prev parent reply other threads:[~2024-03-22 11:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-22 6:09 [PATCH v2 0/2] mm/ksm: fix ksm exec support for prctl Jinjiang Tu
2024-03-22 6:09 ` [PATCH v2 1/2] " Jinjiang Tu
2024-03-22 9:02 ` David Hildenbrand
2024-03-25 2:24 ` Jinjiang Tu
2024-03-25 8:33 ` David Hildenbrand
2024-03-24 0:03 ` kernel test robot
2024-03-25 5:44 ` Dan Carpenter
2024-03-25 6:33 ` Jinjiang Tu
2024-03-22 6:09 ` [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec Jinjiang Tu
2024-03-22 11:43 ` David Hildenbrand [this message]
2024-03-25 2:24 ` Jinjiang Tu
2024-03-25 8:38 ` David Hildenbrand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bf346a9e-32d5-449a-b81e-dc480c2e89d4@redhat.com \
--to=david@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=linux-mm@kvack.org \
--cc=riel@surriel.com \
--cc=shr@devkernel.io \
--cc=sunnanyong@huawei.com \
--cc=tujinjiang@huawei.com \
--cc=wangkefeng.wang@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).