* [PATCH v2 0/2] mm/ksm: add fork-exec support for prctl
@ 2023-09-20 19:01 Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 1/2] mm/ksm: support fork/exec " Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow Stefan Roesch
0 siblings, 2 replies; 5+ messages in thread
From: Stefan Roesch @ 2023-09-20 19:01 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
A process can enable KSM with the prctl system call. When the process is
forked the KSM flag is inherited by the child process. However if the
process is executing an exec system call directly after the fork, the
KSM setting is cleared. This patch series addresses this problem.
1) Change the mask in coredump.h for execing a new process
2) Add a new test case in ksm_functional_tests
Changes:
- V2:
- Removed the child program from the patch series
- Child program is implemented by the program itself
- Added a new command line parameter for the child program
- Removed new section from Makefile
- Removed duplicate ; charaters
- Added return in if clause
- Used PR_GET_MEMORY_MERGE instead of magic numbers
- Resetting PR_SET_MEMROY_MERGE at the end.
Stefan Roesch (2):
mm/ksm: support fork/exec for prctl
mm/ksm: Test case for prctl fork/exec workflow
include/linux/sched/coredump.h | 7 +-
.../selftests/mm/ksm_functional_tests.c | 67 ++++++++++++++++++-
2 files changed, 71 insertions(+), 3 deletions(-)
base-commit: 15bcc9730fcd7526a3b92eff105d6701767a53bb
--
2.39.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] mm/ksm: support fork/exec for prctl
2023-09-20 19:01 [PATCH v2 0/2] mm/ksm: add fork-exec support for prctl Stefan Roesch
@ 2023-09-20 19:01 ` Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow Stefan Roesch
1 sibling, 0 replies; 5+ messages in thread
From: Stefan Roesch @ 2023-09-20 19:01 UTC (permalink / raw)
To: kernel-team
Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm, Carl Klemm
A process can enable KSM with the prctl system call. When the process is
forked the KSM flag is inherited by the child process. However if the
process is executing an exec system call directly after the fork, the
KSM setting is cleared. This patch addresses this problem.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
Fixes: d7597f59d1d3 ("mm: add new api to enable ksm per process")
Reviewed-by: David Hildenbrand <david@redhat.com>
Reported-by: Carl Klemm <carl@uvos.xyz>
Tested-by: Carl Klemm <carl@uvos.xyz>
---
include/linux/sched/coredump.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/sched/coredump.h b/include/linux/sched/coredump.h
index 0ee96ea7a0e9..205aa9917394 100644
--- a/include/linux/sched/coredump.h
+++ b/include/linux/sched/coredump.h
@@ -87,8 +87,11 @@ static inline int get_dumpable(struct mm_struct *mm)
#define MMF_DISABLE_THP_MASK (1 << MMF_DISABLE_THP)
+#define MMF_VM_MERGE_ANY 29
+#define MMF_VM_MERGE_ANY_MASK (1 << MMF_VM_MERGE_ANY)
+
#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK |\
- MMF_DISABLE_THP_MASK | MMF_HAS_MDWE_MASK)
+ MMF_DISABLE_THP_MASK | MMF_HAS_MDWE_MASK |\
+ MMF_VM_MERGE_ANY_MASK)
-#define MMF_VM_MERGE_ANY 29
#endif /* _LINUX_SCHED_COREDUMP_H */
--
2.39.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow
2023-09-20 19:01 [PATCH v2 0/2] mm/ksm: add fork-exec support for prctl Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 1/2] mm/ksm: support fork/exec " Stefan Roesch
@ 2023-09-20 19:01 ` Stefan Roesch
2023-09-21 11:44 ` David Hildenbrand
1 sibling, 1 reply; 5+ messages in thread
From: Stefan Roesch @ 2023-09-20 19:01 UTC (permalink / raw)
To: kernel-team; +Cc: shr, akpm, david, hannes, riel, linux-kernel, linux-mm
This adds a new test case to the ksm functional tests to make sure that
the KSM setting is inherited by the child process when doing a
fork/exec.
Signed-off-by: Stefan Roesch <shr@devkernel.io>
---
.../selftests/mm/ksm_functional_tests.c | 67 ++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c
index 901e950f9138..40b86c9caf3a 100644
--- a/tools/testing/selftests/mm/ksm_functional_tests.c
+++ b/tools/testing/selftests/mm/ksm_functional_tests.c
@@ -26,6 +26,7 @@
#define KiB 1024u
#define MiB (1024 * KiB)
+#define FORK_EXEC_CHILD_PRG_NAME "ksm_fork_exec_child"
static int mem_fd;
static int ksm_fd;
@@ -479,6 +480,65 @@ static void test_prctl_fork(void)
ksft_test_result_pass("PR_SET_MEMORY_MERGE value is inherited\n");
}
+static int ksm_fork_exec_child(void)
+{
+ /* Test if KSM is enabled for the process. */
+ int ksm = prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0);
+ return ksm == 1;
+}
+
+static void test_prctl_fork_exec(void)
+{
+ int ret, status;
+ pid_t child_pid;
+
+ ksft_print_msg("[RUN] %s\n", __func__);
+
+ ret = prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0);
+ if (ret < 0 && errno == EINVAL) {
+ ksft_test_result_skip("PR_SET_MEMORY_MERGE not supported\n");
+ return;
+ } else if (ret) {
+ ksft_test_result_fail("PR_SET_MEMORY_MERGE=1 failed\n");
+ return;
+ }
+
+ child_pid = fork();
+ if (child_pid == -1) {
+ ksft_test_result_skip("fork() failed\n");
+ return;
+ } else if (child_pid == 0) {
+ char *prg_name = "./ksm_functional_tests";
+ char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME };
+
+ execv(prg_name, argv_for_program);
+ return;
+ }
+
+ if (waitpid(child_pid, &status, 0) > 0) {
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ if (status) {
+ ksft_test_result_fail("KSM not enabled\n");
+ return;
+ }
+ } else {
+ ksft_test_result_fail("program didn't terminate normally\n");
+ return;
+ }
+ } else {
+ ksft_test_result_fail("waitpid() failed\n");
+ return;
+ }
+
+ if (prctl(PR_SET_MEMORY_MERGE, 0, 0, 0, 0)) {
+ ksft_test_result_fail("PR_SET_MEMORY_MERGE=0 failed\n");
+ return;
+ }
+
+ ksft_test_result_pass("PR_SET_MEMORY_MERGE value is inherited\n");
+}
+
static void test_prctl_unmerge(void)
{
const unsigned int size = 2 * MiB;
@@ -536,9 +596,13 @@ static void test_prot_none(void)
int main(int argc, char **argv)
{
- unsigned int tests = 7;
+ unsigned int tests = 8;
int err;
+ if (argc > 1 && !strcmp(argv[1], FORK_EXEC_CHILD_PRG_NAME)) {
+ exit(ksm_fork_exec_child() == 1 ? 0 : 1);
+ }
+
#ifdef __NR_userfaultfd
tests++;
#endif
@@ -576,6 +640,7 @@ int main(int argc, char **argv)
test_prctl();
test_prctl_fork();
+ test_prctl_fork_exec();
test_prctl_unmerge();
err = ksft_get_fail_cnt();
--
2.39.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow
2023-09-20 19:01 ` [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow Stefan Roesch
@ 2023-09-21 11:44 ` David Hildenbrand
2023-09-21 16:25 ` Stefan Roesch
0 siblings, 1 reply; 5+ messages in thread
From: David Hildenbrand @ 2023-09-21 11:44 UTC (permalink / raw)
To: Stefan Roesch, kernel-team; +Cc: akpm, hannes, riel, linux-kernel, linux-mm
On 20.09.23 21:01, Stefan Roesch wrote:
> This adds a new test case to the ksm functional tests to make sure that
> the KSM setting is inherited by the child process when doing a
> fork/exec.
>
> Signed-off-by: Stefan Roesch <shr@devkernel.io>
> ---
> .../selftests/mm/ksm_functional_tests.c | 67 ++++++++++++++++++-
> 1 file changed, 66 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c b/tools/testing/selftests/mm/ksm_functional_tests.c
> index 901e950f9138..40b86c9caf3a 100644
> --- a/tools/testing/selftests/mm/ksm_functional_tests.c
> +++ b/tools/testing/selftests/mm/ksm_functional_tests.c
> @@ -26,6 +26,7 @@
>
> #define KiB 1024u
> #define MiB (1024 * KiB)
> +#define FORK_EXEC_CHILD_PRG_NAME "ksm_fork_exec_child"
>
> static int mem_fd;
> static int ksm_fd;
> @@ -479,6 +480,65 @@ static void test_prctl_fork(void)
> ksft_test_result_pass("PR_SET_MEMORY_MERGE value is inherited\n");
> }
>
> +static int ksm_fork_exec_child(void)
> +{
> + /* Test if KSM is enabled for the process. */
> + int ksm = prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0);
> + return ksm == 1;
You can simply do "return prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) == 1;"
Or maybe even "return prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0);" and
adjust the comparison below in the caller.
> +}
> +
> +static void test_prctl_fork_exec(void)
> +{
> + int ret, status;
> + pid_t child_pid;
> +
> + ksft_print_msg("[RUN] %s\n", __func__);
> +
> + ret = prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0);
> + if (ret < 0 && errno == EINVAL) {
> + ksft_test_result_skip("PR_SET_MEMORY_MERGE not supported\n");
> + return;
> + } else if (ret) {
> + ksft_test_result_fail("PR_SET_MEMORY_MERGE=1 failed\n");
> + return;
> + }
> +
> + child_pid = fork();
> + if (child_pid == -1) {
> + ksft_test_result_skip("fork() failed\n");
> + return;
> + } else if (child_pid == 0) {
> + char *prg_name = "./ksm_functional_tests";
> + char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME };
> +
I'd simply have used the magic number "1" or so. But this works as well.
Reviewed-by: David Hildenbrand <david@redhat.com>
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow
2023-09-21 11:44 ` David Hildenbrand
@ 2023-09-21 16:25 ` Stefan Roesch
0 siblings, 0 replies; 5+ messages in thread
From: Stefan Roesch @ 2023-09-21 16:25 UTC (permalink / raw)
To: David Hildenbrand; +Cc: kernel-team, akpm, hannes, riel, linux-kernel, linux-mm
David Hildenbrand <david@redhat.com> writes:
> On 20.09.23 21:01, Stefan Roesch wrote:
>> This adds a new test case to the ksm functional tests to make sure that
>> the KSM setting is inherited by the child process when doing a
>> fork/exec.
>> Signed-off-by: Stefan Roesch <shr@devkernel.io>
>> ---
>> .../selftests/mm/ksm_functional_tests.c | 67 ++++++++++++++++++-
>> 1 file changed, 66 insertions(+), 1 deletion(-)
>> diff --git a/tools/testing/selftests/mm/ksm_functional_tests.c
>> b/tools/testing/selftests/mm/ksm_functional_tests.c
>> index 901e950f9138..40b86c9caf3a 100644
>> --- a/tools/testing/selftests/mm/ksm_functional_tests.c
>> +++ b/tools/testing/selftests/mm/ksm_functional_tests.c
>> @@ -26,6 +26,7 @@
>> #define KiB 1024u
>> #define MiB (1024 * KiB)
>> +#define FORK_EXEC_CHILD_PRG_NAME "ksm_fork_exec_child"
>> static int mem_fd;
>> static int ksm_fd;
>> @@ -479,6 +480,65 @@ static void test_prctl_fork(void)
>> ksft_test_result_pass("PR_SET_MEMORY_MERGE value is inherited\n");
>> }
>> +static int ksm_fork_exec_child(void)
>> +{
>> + /* Test if KSM is enabled for the process. */
>> + int ksm = prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0);
>> + return ksm == 1;
>
> You can simply do "return prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0) == 1;"
>
> Or maybe even "return prctl(PR_GET_MEMORY_MERGE, 0, 0, 0, 0);" and adjust the
> comparison below in the caller.
>
I'll use the first one, then its all in one place.
>> +}
>> +
>> +static void test_prctl_fork_exec(void)
>> +{
>> + int ret, status;
>> + pid_t child_pid;
>> +
>> + ksft_print_msg("[RUN] %s\n", __func__);
>> +
>> + ret = prctl(PR_SET_MEMORY_MERGE, 1, 0, 0, 0);
>> + if (ret < 0 && errno == EINVAL) {
>> + ksft_test_result_skip("PR_SET_MEMORY_MERGE not supported\n");
>> + return;
>> + } else if (ret) {
>> + ksft_test_result_fail("PR_SET_MEMORY_MERGE=1 failed\n");
>> + return;
>> + }
>> +
>> + child_pid = fork();
>> + if (child_pid == -1) {
>> + ksft_test_result_skip("fork() failed\n");
>> + return;
>> + } else if (child_pid == 0) {
>> + char *prg_name = "./ksm_functional_tests";
>> + char *argv_for_program[] = { prg_name, FORK_EXEC_CHILD_PRG_NAME };
>> +
>
> I'd simply have used the magic number "1" or so. But this works as well.
>
I think the current one makes it easier in case we have to add a second
one later.
> Reviewed-by: David Hildenbrand <david@redhat.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-09-21 16:27 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-20 19:01 [PATCH v2 0/2] mm/ksm: add fork-exec support for prctl Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 1/2] mm/ksm: support fork/exec " Stefan Roesch
2023-09-20 19:01 ` [PATCH v2 2/2] mm/ksm: Test case for prctl fork/exec workflow Stefan Roesch
2023-09-21 11:44 ` David Hildenbrand
2023-09-21 16:25 ` Stefan Roesch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox