* [PATCH v2 0/2] mm/ksm: fix ksm exec support for prctl
@ 2024-03-22 6:09 Jinjiang Tu
2024-03-22 6:09 ` [PATCH v2 1/2] " 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
0 siblings, 2 replies; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-22 6:09 UTC (permalink / raw)
To: akpm, david, shr, hannes, riel, wangkefeng.wang, sunnanyong, linux-mm
Cc: tujinjiang
commit 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") inherits
MMF_VM_MERGE_ANY flag when a task calls execve(). Howerver, it doesn't
create the mm_slot, so ksmd will not try to scan this task. The first
patch fixes the issue.
The second patch extend the selftests of ksm to verfity the deduplication
really happens after fork/exec inherits ths KSM setting.
Changelog since v1:
- Add ksm cleanup in __bprm_mm_init() when error occurs.
- Add some comment.
- Extend the selftests of ksm fork/exec.
Jinjiang Tu (2):
mm/ksm: fix ksm exec support for prctl
selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
fs/exec.c | 10 +++
include/linux/ksm.h | 13 +++
.../selftests/mm/ksm_functional_tests.c | 79 +++++++++++++++++--
3 files changed, 96 insertions(+), 6 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-22 6:09 [PATCH v2 0/2] mm/ksm: fix ksm exec support for prctl Jinjiang Tu
@ 2024-03-22 6:09 ` Jinjiang Tu
2024-03-22 9:02 ` David Hildenbrand
` (2 more replies)
2024-03-22 6:09 ` [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec Jinjiang Tu
1 sibling, 3 replies; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-22 6:09 UTC (permalink / raw)
To: akpm, david, shr, hannes, riel, wangkefeng.wang, sunnanyong, linux-mm
Cc: tujinjiang
commit 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") inherits
MMF_VM_MERGE_ANY flag when a task calls execve(). Howerver, it doesn't
create the mm_slot, so ksmd will not try to scan this task.
To fix it, allocate and add the mm_slot to ksm_mm_head in __bprm_mm_init()
when the mm has MMF_VM_MERGE_ANY flag.
Fixes: 3c6f33b7273a ("mm/ksm: support fork/exec for prctl")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
---
fs/exec.c | 10 ++++++++++
include/linux/ksm.h | 13 +++++++++++++
2 files changed, 23 insertions(+)
diff --git a/fs/exec.c b/fs/exec.c
index ff6f26671cfc..66202d016a0a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -67,6 +67,7 @@
#include <linux/time_namespace.h>
#include <linux/user_events.h>
#include <linux/rseq.h>
+#include <linux/ksm.h>
#include <linux/uaccess.h>
#include <asm/mmu_context.h>
@@ -267,6 +268,13 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
goto err_free;
}
+ /*
+ * Need to be called with mmap write lock
+ * held, to avoid race with ksmd.
+ */
+ if (ksm_execve(mm))
+ goto err_ksm;
+
/*
* Place the stack at the largest stack address the architecture
* supports. Later, we'll move this to an appropriate place. We don't
@@ -288,6 +296,8 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
bprm->p = vma->vm_end - sizeof(void *);
return 0;
err:
+ ksm_exit(mm);
+err_ksm:
mmap_write_unlock(mm);
err_free:
bprm->vma = NULL;
diff --git a/include/linux/ksm.h b/include/linux/ksm.h
index 401348e9f92b..7e2b1de3996a 100644
--- a/include/linux/ksm.h
+++ b/include/linux/ksm.h
@@ -59,6 +59,14 @@ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
return 0;
}
+static inline int ksm_execve(struct mm_struct *mm)
+{
+ if (test_bit(MMF_VM_MERGE_ANY, &mm->flags))
+ return __ksm_enter(mm);
+
+ return 0;
+}
+
static inline void ksm_exit(struct mm_struct *mm)
{
if (test_bit(MMF_VM_MERGEABLE, &mm->flags))
@@ -107,6 +115,11 @@ static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
return 0;
}
+static inline int ksm_execve(struct mm_struct *mm)
+{
+ return 0;
+}
+
static inline void ksm_exit(struct mm_struct *mm)
{
}
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
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 6:09 ` Jinjiang Tu
2024-03-22 11:43 ` David Hildenbrand
1 sibling, 1 reply; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-22 6:09 UTC (permalink / raw)
To: akpm, david, shr, hannes, riel, wangkefeng.wang, sunnanyong, linux-mm
Cc: tujinjiang
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;
+ }
+
+ 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)
+ return -2;
+
+ return 0;
}
static void test_prctl_fork_exec(void)
@@ -517,9 +581,12 @@ static void test_prctl_fork_exec(void)
if (waitpid(child_pid, &status, 0) > 0) {
if (WIFEXITED(status)) {
status = WEXITSTATUS(status);
- if (status) {
+ if (status == -1) {
ksft_test_result_fail("KSM not enabled\n");
return;
+ } else if (status == -2) {
+ ksft_test_result_fail("fail to merge in child\n");
+ return;
}
} else {
ksft_test_result_fail("program didn't terminate normally\n");
@@ -599,7 +666,7 @@ int main(int argc, char **argv)
int err;
if (argc > 1 && !strcmp(argv[1], FORK_EXEC_CHILD_PRG_NAME)) {
- exit(ksm_fork_exec_child() == 1 ? 0 : 1);
+ exit(ksm_fork_exec_child());
}
#ifdef __NR_userfaultfd
--
2.25.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
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-24 0:03 ` kernel test robot
2024-03-25 5:44 ` Dan Carpenter
2 siblings, 1 reply; 13+ messages in thread
From: David Hildenbrand @ 2024-03-22 9:02 UTC (permalink / raw)
To: Jinjiang Tu, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
On 22.03.24 07:09, Jinjiang Tu wrote:
> commit 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") inherits
> MMF_VM_MERGE_ANY flag when a task calls execve(). Howerver, it doesn't
> create the mm_slot, so ksmd will not try to scan this task.
>
> To fix it, allocate and add the mm_slot to ksm_mm_head in __bprm_mm_init()
> when the mm has MMF_VM_MERGE_ANY flag.
>
> Fixes: 3c6f33b7273a ("mm/ksm: support fork/exec for prctl")
> Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
> ---
> fs/exec.c | 10 ++++++++++
> include/linux/ksm.h | 13 +++++++++++++
> 2 files changed, 23 insertions(+)
>
> diff --git a/fs/exec.c b/fs/exec.c
> index ff6f26671cfc..66202d016a0a 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -67,6 +67,7 @@
> #include <linux/time_namespace.h>
> #include <linux/user_events.h>
> #include <linux/rseq.h>
> +#include <linux/ksm.h>
>
> #include <linux/uaccess.h>
> #include <asm/mmu_context.h>
> @@ -267,6 +268,13 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
> goto err_free;
> }
>
> + /*
> + * Need to be called with mmap write lock
> + * held, to avoid race with ksmd.
> + */
> + if (ksm_execve(mm))
> + goto err_ksm;
> +
But now, would we revert what insert_vm_struct() did?
We're freeing the VMA later, but we might have accounted memory.
What would be cleaner is doing the ksm_execve() before the
insert_vm_struct(), and then cleaning up in case insert_vm_struct() failed.
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
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
2024-03-25 2:24 ` Jinjiang Tu
0 siblings, 1 reply; 13+ messages in thread
From: David Hildenbrand @ 2024-03-22 11:43 UTC (permalink / raw)
To: Jinjiang Tu, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
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
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-22 6:09 ` [PATCH v2 1/2] " Jinjiang Tu
2024-03-22 9:02 ` David Hildenbrand
@ 2024-03-24 0:03 ` kernel test robot
2024-03-25 5:44 ` Dan Carpenter
2 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2024-03-24 0:03 UTC (permalink / raw)
To: Jinjiang Tu, akpm, david, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
Cc: llvm, oe-kbuild-all, tujinjiang
Hi Jinjiang,
kernel test robot noticed the following build warnings:
[auto build test WARNING on akpm-mm/mm-everything]
url: https://github.com/intel-lab-lkp/linux/commits/Jinjiang-Tu/mm-ksm-fix-ksm-exec-support-for-prctl/20240322-141317
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20240322060947.3254967-2-tujinjiang%40huawei.com
patch subject: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
config: s390-allnoconfig (https://download.01.org/0day-ci/archive/20240324/202403240716.8B7CiDbr-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 23de3862dce582ce91c1aa914467d982cb1a73b4)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240324/202403240716.8B7CiDbr-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403240716.8B7CiDbr-lkp@intel.com/
All warnings (new ones prefixed by >>):
In file included from fs/exec.c:30:
In file included from include/linux/mm.h:2211:
include/linux/vmstat.h:514:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
514 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
>> fs/exec.c:275:6: warning: variable 'err' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]
275 | if (ksm_execve(mm))
| ^~~~~~~~~~~~~~
fs/exec.c:305:9: note: uninitialized use occurs here
305 | return err;
| ^~~
fs/exec.c:275:2: note: remove the 'if' if its condition is always false
275 | if (ksm_execve(mm))
| ^~~~~~~~~~~~~~~~~~~
276 | goto err_ksm;
| ~~~~~~~~~~~~
fs/exec.c:257:9: note: initialize the variable 'err' to silence this warning
257 | int err;
| ^
| = 0
2 warnings generated.
vim +275 fs/exec.c
254
255 static int __bprm_mm_init(struct linux_binprm *bprm)
256 {
257 int err;
258 struct vm_area_struct *vma = NULL;
259 struct mm_struct *mm = bprm->mm;
260
261 bprm->vma = vma = vm_area_alloc(mm);
262 if (!vma)
263 return -ENOMEM;
264 vma_set_anonymous(vma);
265
266 if (mmap_write_lock_killable(mm)) {
267 err = -EINTR;
268 goto err_free;
269 }
270
271 /*
272 * Need to be called with mmap write lock
273 * held, to avoid race with ksmd.
274 */
> 275 if (ksm_execve(mm))
276 goto err_ksm;
277
278 /*
279 * Place the stack at the largest stack address the architecture
280 * supports. Later, we'll move this to an appropriate place. We don't
281 * use STACK_TOP because that can depend on attributes which aren't
282 * configured yet.
283 */
284 BUILD_BUG_ON(VM_STACK_FLAGS & VM_STACK_INCOMPLETE_SETUP);
285 vma->vm_end = STACK_TOP_MAX;
286 vma->vm_start = vma->vm_end - PAGE_SIZE;
287 vm_flags_init(vma, VM_SOFTDIRTY | VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP);
288 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
289
290 err = insert_vm_struct(mm, vma);
291 if (err)
292 goto err;
293
294 mm->stack_vm = mm->total_vm = 1;
295 mmap_write_unlock(mm);
296 bprm->p = vma->vm_end - sizeof(void *);
297 return 0;
298 err:
299 ksm_exit(mm);
300 err_ksm:
301 mmap_write_unlock(mm);
302 err_free:
303 bprm->vma = NULL;
304 vm_area_free(vma);
305 return err;
306 }
307
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-22 9:02 ` David Hildenbrand
@ 2024-03-25 2:24 ` Jinjiang Tu
2024-03-25 8:33 ` David Hildenbrand
0 siblings, 1 reply; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-25 2:24 UTC (permalink / raw)
To: David Hildenbrand, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
在 2024/3/22 17:02, David Hildenbrand 写道:
> On 22.03.24 07:09, Jinjiang Tu wrote:
>> commit 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") inherits
>> MMF_VM_MERGE_ANY flag when a task calls execve(). Howerver, it doesn't
>> create the mm_slot, so ksmd will not try to scan this task.
>>
>> To fix it, allocate and add the mm_slot to ksm_mm_head in
>> __bprm_mm_init()
>> when the mm has MMF_VM_MERGE_ANY flag.
>>
>> Fixes: 3c6f33b7273a ("mm/ksm: support fork/exec for prctl")
>> Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
>> ---
>> fs/exec.c | 10 ++++++++++
>> include/linux/ksm.h | 13 +++++++++++++
>> 2 files changed, 23 insertions(+)
>>
>> diff --git a/fs/exec.c b/fs/exec.c
>> index ff6f26671cfc..66202d016a0a 100644
>> --- a/fs/exec.c
>> +++ b/fs/exec.c
>> @@ -67,6 +67,7 @@
>> #include <linux/time_namespace.h>
>> #include <linux/user_events.h>
>> #include <linux/rseq.h>
>> +#include <linux/ksm.h>
>> #include <linux/uaccess.h>
>> #include <asm/mmu_context.h>
>> @@ -267,6 +268,13 @@ static int __bprm_mm_init(struct linux_binprm
>> *bprm)
>> goto err_free;
>> }
>> + /*
>> + * Need to be called with mmap write lock
>> + * held, to avoid race with ksmd.
>> + */
>> + if (ksm_execve(mm))
>> + goto err_ksm;
>> +
>
> But now, would we revert what insert_vm_struct() did?
>
> We're freeing the VMA later, but we might have accounted memory.
>
>
> What would be cleaner is doing the ksm_execve() before the
> insert_vm_struct(), and then cleaning up in case insert_vm_struct()
> failed.
In fact, ksm_execve() has been called before the insert_vm_struct() in
this patch.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
2024-03-22 11:43 ` David Hildenbrand
@ 2024-03-25 2:24 ` Jinjiang Tu
2024-03-25 8:38 ` David Hildenbrand
0 siblings, 1 reply; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-25 2:24 UTC (permalink / raw)
To: David Hildenbrand, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
在 2024/3/22 19:43, David Hildenbrand 写道:
> 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);
I have considered this before. But, mmap_and_merge_range() calls
ksft_test_result_fail() when error occurs, ksft_test_result_fail()
prints prefixed with ksft_fail count. When mmap_and_merge_range() is
called in the child process, the ksft_fail isn't consisent with the
parent process due to the global variable ksft_fail is CoWed. As a
result, ksft_print_msg() is intended to be called in child process.
Maybe, We could introduce a macro ksm_print() to control which function
is called according to ksm_merge_mode :
#define ksm_print(mode, fmt, ...) do { \
if ((mode) == KSM_MERGE_NONE) \
ksft_print_msg(fmt, ##__VA_ARGS__);\
else \
ksft_test_result_fail(fmt, ##__VA_ARGS__);\
} while (0)
>
> 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;
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-22 6:09 ` [PATCH v2 1/2] " Jinjiang Tu
2024-03-22 9:02 ` David Hildenbrand
2024-03-24 0:03 ` kernel test robot
@ 2024-03-25 5:44 ` Dan Carpenter
2024-03-25 6:33 ` Jinjiang Tu
2 siblings, 1 reply; 13+ messages in thread
From: Dan Carpenter @ 2024-03-25 5:44 UTC (permalink / raw)
To: oe-kbuild, Jinjiang Tu, akpm, david, shr, hannes, riel,
wangkefeng.wang, sunnanyong, linux-mm
Cc: lkp, oe-kbuild-all, tujinjiang
Hi Jinjiang,
kernel test robot noticed the following build warnings:
url: https://github.com/intel-lab-lkp/linux/commits/Jinjiang-Tu/mm-ksm-fix-ksm-exec-support-for-prctl/20240322-141317
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20240322060947.3254967-2-tujinjiang%40huawei.com
patch subject: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
config: openrisc-randconfig-r081-20240322 (https://download.01.org/0day-ci/archive/20240324/202403240146.Pv4gVc5N-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202403240146.Pv4gVc5N-lkp@intel.com/
smatch warnings:
fs/exec.c:305 __bprm_mm_init() error: uninitialized symbol 'err'.
vim +/err +305 fs/exec.c
b6a2fea39318e43 Ollie Wild 2007-07-19 255 static int __bprm_mm_init(struct linux_binprm *bprm)
b6a2fea39318e43 Ollie Wild 2007-07-19 256 {
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 257 int err;
b6a2fea39318e43 Ollie Wild 2007-07-19 258 struct vm_area_struct *vma = NULL;
b6a2fea39318e43 Ollie Wild 2007-07-19 259 struct mm_struct *mm = bprm->mm;
b6a2fea39318e43 Ollie Wild 2007-07-19 260
490fc053865c9cc Linus Torvalds 2018-07-21 261 bprm->vma = vma = vm_area_alloc(mm);
b6a2fea39318e43 Ollie Wild 2007-07-19 262 if (!vma)
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 263 return -ENOMEM;
bfd40eaff5abb9f Kirill A. Shutemov 2018-07-26 264 vma_set_anonymous(vma);
b6a2fea39318e43 Ollie Wild 2007-07-19 265
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 266 if (mmap_write_lock_killable(mm)) {
f268dfe905d4682 Michal Hocko 2016-05-23 267 err = -EINTR;
f268dfe905d4682 Michal Hocko 2016-05-23 268 goto err_free;
f268dfe905d4682 Michal Hocko 2016-05-23 269 }
b6a2fea39318e43 Ollie Wild 2007-07-19 270
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 271 /*
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 272 * Need to be called with mmap write lock
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 273 * held, to avoid race with ksmd.
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 274 */
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 275 if (ksm_execve(mm))
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 276 goto err_ksm;
"err" not set before the goto.
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 277
b6a2fea39318e43 Ollie Wild 2007-07-19 278 /*
b6a2fea39318e43 Ollie Wild 2007-07-19 279 * Place the stack at the largest stack address the architecture
b6a2fea39318e43 Ollie Wild 2007-07-19 280 * supports. Later, we'll move this to an appropriate place. We don't
b6a2fea39318e43 Ollie Wild 2007-07-19 281 * use STACK_TOP because that can depend on attributes which aren't
b6a2fea39318e43 Ollie Wild 2007-07-19 282 * configured yet.
b6a2fea39318e43 Ollie Wild 2007-07-19 283 */
aacb3d17a73f644 Michal Hocko 2011-07-26 284 BUILD_BUG_ON(VM_STACK_FLAGS & VM_STACK_INCOMPLETE_SETUP);
b6a2fea39318e43 Ollie Wild 2007-07-19 285 vma->vm_end = STACK_TOP_MAX;
b6a2fea39318e43 Ollie Wild 2007-07-19 286 vma->vm_start = vma->vm_end - PAGE_SIZE;
1c71222e5f2393b Suren Baghdasaryan 2023-01-26 287 vm_flags_init(vma, VM_SOFTDIRTY | VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP);
3ed75eb8f1cd895 Coly Li 2007-10-18 288 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
462e635e5b73ba9 Tavis Ormandy 2010-12-09 289
b6a2fea39318e43 Ollie Wild 2007-07-19 290 err = insert_vm_struct(mm, vma);
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 291 if (err)
b6a2fea39318e43 Ollie Wild 2007-07-19 292 goto err;
b6a2fea39318e43 Ollie Wild 2007-07-19 293
b6a2fea39318e43 Ollie Wild 2007-07-19 294 mm->stack_vm = mm->total_vm = 1;
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 295 mmap_write_unlock(mm);
b6a2fea39318e43 Ollie Wild 2007-07-19 296 bprm->p = vma->vm_end - sizeof(void *);
b6a2fea39318e43 Ollie Wild 2007-07-19 297 return 0;
b6a2fea39318e43 Ollie Wild 2007-07-19 298 err:
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 299 ksm_exit(mm);
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 300 err_ksm:
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 301 mmap_write_unlock(mm);
f268dfe905d4682 Michal Hocko 2016-05-23 302 err_free:
b6a2fea39318e43 Ollie Wild 2007-07-19 303 bprm->vma = NULL;
3928d4f5ee37cdc Linus Torvalds 2018-07-21 304 vm_area_free(vma);
b6a2fea39318e43 Ollie Wild 2007-07-19 @305 return err;
b6a2fea39318e43 Ollie Wild 2007-07-19 306 }
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-25 5:44 ` Dan Carpenter
@ 2024-03-25 6:33 ` Jinjiang Tu
0 siblings, 0 replies; 13+ messages in thread
From: Jinjiang Tu @ 2024-03-25 6:33 UTC (permalink / raw)
To: Dan Carpenter, oe-kbuild, akpm, david, shr, hannes, riel,
wangkefeng.wang, sunnanyong, linux-mm
Cc: lkp, oe-kbuild-all
在 2024/3/25 13:44, Dan Carpenter 写道:
> Hi Jinjiang,
>
> kernel test robot noticed the following build warnings:
>
> url: https://github.com/intel-lab-lkp/linux/commits/Jinjiang-Tu/mm-ksm-fix-ksm-exec-support-for-prctl/20240322-141317
> base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
> patch link: https://lore.kernel.org/r/20240322060947.3254967-2-tujinjiang%40huawei.com
> patch subject: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
> config: openrisc-randconfig-r081-20240322 (https://download.01.org/0day-ci/archive/20240324/202403240146.Pv4gVc5N-lkp@intel.com/config)
> compiler: or1k-linux-gcc (GCC) 13.2.0
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
> | Closes: https://lore.kernel.org/r/202403240146.Pv4gVc5N-lkp@intel.com/
>
> smatch warnings:
> fs/exec.c:305 __bprm_mm_init() error: uninitialized symbol 'err'.
>
> vim +/err +305 fs/exec.c
>
> b6a2fea39318e43 Ollie Wild 2007-07-19 255 static int __bprm_mm_init(struct linux_binprm *bprm)
> b6a2fea39318e43 Ollie Wild 2007-07-19 256 {
> eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 257 int err;
> b6a2fea39318e43 Ollie Wild 2007-07-19 258 struct vm_area_struct *vma = NULL;
> b6a2fea39318e43 Ollie Wild 2007-07-19 259 struct mm_struct *mm = bprm->mm;
> b6a2fea39318e43 Ollie Wild 2007-07-19 260
> 490fc053865c9cc Linus Torvalds 2018-07-21 261 bprm->vma = vma = vm_area_alloc(mm);
> b6a2fea39318e43 Ollie Wild 2007-07-19 262 if (!vma)
> eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 263 return -ENOMEM;
> bfd40eaff5abb9f Kirill A. Shutemov 2018-07-26 264 vma_set_anonymous(vma);
> b6a2fea39318e43 Ollie Wild 2007-07-19 265
> d8ed45c5dcd455f Michel Lespinasse 2020-06-08 266 if (mmap_write_lock_killable(mm)) {
> f268dfe905d4682 Michal Hocko 2016-05-23 267 err = -EINTR;
> f268dfe905d4682 Michal Hocko 2016-05-23 268 goto err_free;
> f268dfe905d4682 Michal Hocko 2016-05-23 269 }
> b6a2fea39318e43 Ollie Wild 2007-07-19 270
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 271 /*
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 272 * Need to be called with mmap write lock
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 273 * held, to avoid race with ksmd.
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 274 */
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 275 if (ksm_execve(mm))
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 276 goto err_ksm;
>
> "err" not set before the goto.
The code should be:
err = ksm_execve(mm);
if (err)
goto err_ksm;
I will fix in the next version.
>
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 277
> b6a2fea39318e43 Ollie Wild 2007-07-19 278 /*
> b6a2fea39318e43 Ollie Wild 2007-07-19 279 * Place the stack at the largest stack address the architecture
> b6a2fea39318e43 Ollie Wild 2007-07-19 280 * supports. Later, we'll move this to an appropriate place. We don't
> b6a2fea39318e43 Ollie Wild 2007-07-19 281 * use STACK_TOP because that can depend on attributes which aren't
> b6a2fea39318e43 Ollie Wild 2007-07-19 282 * configured yet.
> b6a2fea39318e43 Ollie Wild 2007-07-19 283 */
> aacb3d17a73f644 Michal Hocko 2011-07-26 284 BUILD_BUG_ON(VM_STACK_FLAGS & VM_STACK_INCOMPLETE_SETUP);
> b6a2fea39318e43 Ollie Wild 2007-07-19 285 vma->vm_end = STACK_TOP_MAX;
> b6a2fea39318e43 Ollie Wild 2007-07-19 286 vma->vm_start = vma->vm_end - PAGE_SIZE;
> 1c71222e5f2393b Suren Baghdasaryan 2023-01-26 287 vm_flags_init(vma, VM_SOFTDIRTY | VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP);
> 3ed75eb8f1cd895 Coly Li 2007-10-18 288 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
> 462e635e5b73ba9 Tavis Ormandy 2010-12-09 289
> b6a2fea39318e43 Ollie Wild 2007-07-19 290 err = insert_vm_struct(mm, vma);
> eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 291 if (err)
> b6a2fea39318e43 Ollie Wild 2007-07-19 292 goto err;
> b6a2fea39318e43 Ollie Wild 2007-07-19 293
> b6a2fea39318e43 Ollie Wild 2007-07-19 294 mm->stack_vm = mm->total_vm = 1;
> d8ed45c5dcd455f Michel Lespinasse 2020-06-08 295 mmap_write_unlock(mm);
> b6a2fea39318e43 Ollie Wild 2007-07-19 296 bprm->p = vma->vm_end - sizeof(void *);
> b6a2fea39318e43 Ollie Wild 2007-07-19 297 return 0;
> b6a2fea39318e43 Ollie Wild 2007-07-19 298 err:
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 299 ksm_exit(mm);
> d282f6b19afd1a9 Jinjiang Tu 2024-03-22 300 err_ksm:
> d8ed45c5dcd455f Michel Lespinasse 2020-06-08 301 mmap_write_unlock(mm);
> f268dfe905d4682 Michal Hocko 2016-05-23 302 err_free:
> b6a2fea39318e43 Ollie Wild 2007-07-19 303 bprm->vma = NULL;
> 3928d4f5ee37cdc Linus Torvalds 2018-07-21 304 vm_area_free(vma);
> b6a2fea39318e43 Ollie Wild 2007-07-19 @305 return err;
> b6a2fea39318e43 Ollie Wild 2007-07-19 306 }
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
2024-03-25 2:24 ` Jinjiang Tu
@ 2024-03-25 8:33 ` David Hildenbrand
0 siblings, 0 replies; 13+ messages in thread
From: David Hildenbrand @ 2024-03-25 8:33 UTC (permalink / raw)
To: Jinjiang Tu, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
On 25.03.24 03:24, Jinjiang Tu wrote:
>
> 在 2024/3/22 17:02, David Hildenbrand 写道:
>> On 22.03.24 07:09, Jinjiang Tu wrote:
>>> commit 3c6f33b7273a ("mm/ksm: support fork/exec for prctl") inherits
>>> MMF_VM_MERGE_ANY flag when a task calls execve(). Howerver, it doesn't
>>> create the mm_slot, so ksmd will not try to scan this task.
>>>
>>> To fix it, allocate and add the mm_slot to ksm_mm_head in
>>> __bprm_mm_init()
>>> when the mm has MMF_VM_MERGE_ANY flag.
>>>
>>> Fixes: 3c6f33b7273a ("mm/ksm: support fork/exec for prctl")
>>> Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
>>> ---
>>> fs/exec.c | 10 ++++++++++
>>> include/linux/ksm.h | 13 +++++++++++++
>>> 2 files changed, 23 insertions(+)
>>>
>>> diff --git a/fs/exec.c b/fs/exec.c
>>> index ff6f26671cfc..66202d016a0a 100644
>>> --- a/fs/exec.c
>>> +++ b/fs/exec.c
>>> @@ -67,6 +67,7 @@
>>> #include <linux/time_namespace.h>
>>> #include <linux/user_events.h>
>>> #include <linux/rseq.h>
>>> +#include <linux/ksm.h>
>>> #include <linux/uaccess.h>
>>> #include <asm/mmu_context.h>
>>> @@ -267,6 +268,13 @@ static int __bprm_mm_init(struct linux_binprm
>>> *bprm)
>>> goto err_free;
>>> }
>>> + /*
>>> + * Need to be called with mmap write lock
>>> + * held, to avoid race with ksmd.
>>> + */
>>> + if (ksm_execve(mm))
>>> + goto err_ksm;
>>> +
>>
>> But now, would we revert what insert_vm_struct() did?
>>
>> We're freeing the VMA later, but we might have accounted memory.
>>
>>
>> What would be cleaner is doing the ksm_execve() before the
>> insert_vm_struct(), and then cleaning up in case insert_vm_struct()
>> failed.
> In fact, ksm_execve() has been called before the insert_vm_struct() in
> this patch.
>
Ahh, I missed that. Indeed, that works then.
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/2] selftest/mm: ksm_functional_tests: extend test case for ksm fork/exec
2024-03-25 2:24 ` Jinjiang Tu
@ 2024-03-25 8:38 ` David Hildenbrand
0 siblings, 0 replies; 13+ messages in thread
From: David Hildenbrand @ 2024-03-25 8:38 UTC (permalink / raw)
To: Jinjiang Tu, akpm, shr, hannes, riel, wangkefeng.wang,
sunnanyong, linux-mm
On 25.03.24 03:24, Jinjiang Tu wrote:
>
> 在 2024/3/22 19:43, David Hildenbrand 写道:
>> 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);
> I have considered this before. But, mmap_and_merge_range() calls
> ksft_test_result_fail() when error occurs, ksft_test_result_fail()
> prints prefixed with ksft_fail count. When mmap_and_merge_range() is
> called in the child process, the ksft_fail isn't consisent with the
> parent process due to the global variable ksft_fail is CoWed. As a
> result, ksft_print_msg() is intended to be called in child process.
>
> Maybe, We could introduce a macro ksm_print() to control which function
> is called according to ksm_merge_mode :
As an alternative, convert all ksft_test_result_fail() in there into
ksft_print_msg(), and in the callers of mmap_and_merge_range(), do
something like
map = mmap_and_merge_range() ...
if (map == MAP_FAILED) {
ksft_test_result_fail("Merging memory failed");
return;
}
--
Cheers,
David / dhildenb
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
@ 2024-03-23 17:24 kernel test robot
0 siblings, 0 replies; 13+ messages in thread
From: kernel test robot @ 2024-03-23 17:24 UTC (permalink / raw)
To: oe-kbuild; +Cc: lkp, Dan Carpenter
BCC: lkp@intel.com
CC: oe-kbuild-all@lists.linux.dev
In-Reply-To: <20240322060947.3254967-2-tujinjiang@huawei.com>
References: <20240322060947.3254967-2-tujinjiang@huawei.com>
TO: Jinjiang Tu <tujinjiang@huawei.com>
TO: akpm@linux-foundation.org
TO: david@redhat.com
TO: shr@devkernel.io
TO: hannes@cmpxchg.org
TO: riel@surriel.com
TO: wangkefeng.wang@huawei.com
TO: sunnanyong@huawei.com
TO: linux-mm@kvack.org
CC: tujinjiang@huawei.com
Hi Jinjiang,
kernel test robot noticed the following build warnings:
[auto build test WARNING on akpm-mm/mm-everything]
url: https://github.com/intel-lab-lkp/linux/commits/Jinjiang-Tu/mm-ksm-fix-ksm-exec-support-for-prctl/20240322-141317
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20240322060947.3254967-2-tujinjiang%40huawei.com
patch subject: [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl
:::::: branch date: 35 hours ago
:::::: commit date: 35 hours ago
config: openrisc-randconfig-r081-20240322 (https://download.01.org/0day-ci/archive/20240324/202403240146.Pv4gVc5N-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <error27@gmail.com>
| Closes: https://lore.kernel.org/r/202403240146.Pv4gVc5N-lkp@intel.com/
smatch warnings:
fs/exec.c:305 __bprm_mm_init() error: uninitialized symbol 'err'.
vim +/err +305 fs/exec.c
b6a2fea39318e43 Ollie Wild 2007-07-19 254
b6a2fea39318e43 Ollie Wild 2007-07-19 255 static int __bprm_mm_init(struct linux_binprm *bprm)
b6a2fea39318e43 Ollie Wild 2007-07-19 256 {
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 257 int err;
b6a2fea39318e43 Ollie Wild 2007-07-19 258 struct vm_area_struct *vma = NULL;
b6a2fea39318e43 Ollie Wild 2007-07-19 259 struct mm_struct *mm = bprm->mm;
b6a2fea39318e43 Ollie Wild 2007-07-19 260
490fc053865c9cc Linus Torvalds 2018-07-21 261 bprm->vma = vma = vm_area_alloc(mm);
b6a2fea39318e43 Ollie Wild 2007-07-19 262 if (!vma)
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 263 return -ENOMEM;
bfd40eaff5abb9f Kirill A. Shutemov 2018-07-26 264 vma_set_anonymous(vma);
b6a2fea39318e43 Ollie Wild 2007-07-19 265
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 266 if (mmap_write_lock_killable(mm)) {
f268dfe905d4682 Michal Hocko 2016-05-23 267 err = -EINTR;
f268dfe905d4682 Michal Hocko 2016-05-23 268 goto err_free;
f268dfe905d4682 Michal Hocko 2016-05-23 269 }
b6a2fea39318e43 Ollie Wild 2007-07-19 270
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 271 /*
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 272 * Need to be called with mmap write lock
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 273 * held, to avoid race with ksmd.
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 274 */
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 275 if (ksm_execve(mm))
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 276 goto err_ksm;
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 277
b6a2fea39318e43 Ollie Wild 2007-07-19 278 /*
b6a2fea39318e43 Ollie Wild 2007-07-19 279 * Place the stack at the largest stack address the architecture
b6a2fea39318e43 Ollie Wild 2007-07-19 280 * supports. Later, we'll move this to an appropriate place. We don't
b6a2fea39318e43 Ollie Wild 2007-07-19 281 * use STACK_TOP because that can depend on attributes which aren't
b6a2fea39318e43 Ollie Wild 2007-07-19 282 * configured yet.
b6a2fea39318e43 Ollie Wild 2007-07-19 283 */
aacb3d17a73f644 Michal Hocko 2011-07-26 284 BUILD_BUG_ON(VM_STACK_FLAGS & VM_STACK_INCOMPLETE_SETUP);
b6a2fea39318e43 Ollie Wild 2007-07-19 285 vma->vm_end = STACK_TOP_MAX;
b6a2fea39318e43 Ollie Wild 2007-07-19 286 vma->vm_start = vma->vm_end - PAGE_SIZE;
1c71222e5f2393b Suren Baghdasaryan 2023-01-26 287 vm_flags_init(vma, VM_SOFTDIRTY | VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP);
3ed75eb8f1cd895 Coly Li 2007-10-18 288 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
462e635e5b73ba9 Tavis Ormandy 2010-12-09 289
b6a2fea39318e43 Ollie Wild 2007-07-19 290 err = insert_vm_struct(mm, vma);
eaccbfa564e48c8 Luiz Fernando N. Capitulino 2009-01-06 291 if (err)
b6a2fea39318e43 Ollie Wild 2007-07-19 292 goto err;
b6a2fea39318e43 Ollie Wild 2007-07-19 293
b6a2fea39318e43 Ollie Wild 2007-07-19 294 mm->stack_vm = mm->total_vm = 1;
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 295 mmap_write_unlock(mm);
b6a2fea39318e43 Ollie Wild 2007-07-19 296 bprm->p = vma->vm_end - sizeof(void *);
b6a2fea39318e43 Ollie Wild 2007-07-19 297 return 0;
b6a2fea39318e43 Ollie Wild 2007-07-19 298 err:
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 299 ksm_exit(mm);
d282f6b19afd1a9 Jinjiang Tu 2024-03-22 300 err_ksm:
d8ed45c5dcd455f Michel Lespinasse 2020-06-08 301 mmap_write_unlock(mm);
f268dfe905d4682 Michal Hocko 2016-05-23 302 err_free:
b6a2fea39318e43 Ollie Wild 2007-07-19 303 bprm->vma = NULL;
3928d4f5ee37cdc Linus Torvalds 2018-07-21 304 vm_area_free(vma);
b6a2fea39318e43 Ollie Wild 2007-07-19 @305 return err;
b6a2fea39318e43 Ollie Wild 2007-07-19 306 }
b6a2fea39318e43 Ollie Wild 2007-07-19 307
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2024-03-25 8:38 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2024-03-25 2:24 ` Jinjiang Tu
2024-03-25 8:38 ` David Hildenbrand
2024-03-23 17:24 [PATCH v2 1/2] mm/ksm: fix ksm exec support for prctl kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.