Skip to content

Commit 985da55

Browse files
lorenzo-stoakesakpm00
authored andcommitted
fork: only invoke khugepaged, ksm hooks if no error
There is no reason to invoke these hooks early against an mm that is in an incomplete state. The change in commit d240629 ("fork: use __mt_dup() to duplicate maple tree in dup_mmap()") makes this more pertinent as we may be in a state where entries in the maple tree are not yet consistent. Their placement early in dup_mmap() only appears to have been meaningful for early error checking, and since functionally it'd require a very small allocation to fail (in practice 'too small to fail') that'd only occur in the most dire circumstances, meaning the fork would fail or be OOM'd in any case. Since both khugepaged and KSM tracking are there to provide optimisations to memory performance rather than critical functionality, it doesn't really matter all that much if, under such dire memory pressure, we fail to register an mm with these. As a result, we follow the example of commit d2081b2 ("mm: khugepaged: make khugepaged_enter() void function") and make ksm_fork() a void function also. We only expose the mm to these functions once we are done with them and only if no error occurred in the fork operation. Link: https://lkml.kernel.org/r/e0cb8b840c9d1d5a6e84d4f8eff5f3f2022aa10c.1729014377.git.lorenzo.stoakes@oracle.com Fixes: d240629 ("fork: use __mt_dup() to duplicate maple tree in dup_mmap()") Signed-off-by: Lorenzo Stoakes <[email protected]> Reported-by: Jann Horn <[email protected]> Reviewed-by: Liam R. Howlett <[email protected]> Reviewed-by: Vlastimil Babka <[email protected]> Reviewed-by: Jann Horn <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Jan Kara <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent f64e67e commit 985da55

File tree

2 files changed

+6
-11
lines changed

2 files changed

+6
-11
lines changed

include/linux/ksm.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,11 @@ static inline long mm_ksm_zero_pages(struct mm_struct *mm)
5454
return atomic_long_read(&mm->ksm_zero_pages);
5555
}
5656

57-
static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
57+
static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
5858
{
59+
/* Adding mm to ksm is best effort on fork. */
5960
if (test_bit(MMF_VM_MERGEABLE, &oldmm->flags))
60-
return __ksm_enter(mm);
61-
62-
return 0;
61+
__ksm_enter(mm);
6362
}
6463

6564
static inline int ksm_execve(struct mm_struct *mm)
@@ -107,9 +106,8 @@ static inline int ksm_disable(struct mm_struct *mm)
107106
return 0;
108107
}
109108

110-
static inline int ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
109+
static inline void ksm_fork(struct mm_struct *mm, struct mm_struct *oldmm)
111110
{
112-
return 0;
113111
}
114112

115113
static inline int ksm_execve(struct mm_struct *mm)

kernel/fork.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -653,11 +653,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
653653
mm->exec_vm = oldmm->exec_vm;
654654
mm->stack_vm = oldmm->stack_vm;
655655

656-
retval = ksm_fork(mm, oldmm);
657-
if (retval)
658-
goto out;
659-
khugepaged_fork(mm, oldmm);
660-
661656
/* Use __mt_dup() to efficiently build an identical maple tree. */
662657
retval = __mt_dup(&oldmm->mm_mt, &mm->mm_mt, GFP_KERNEL);
663658
if (unlikely(retval))
@@ -760,6 +755,8 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
760755
vma_iter_free(&vmi);
761756
if (!retval) {
762757
mt_set_in_rcu(vmi.mas.tree);
758+
ksm_fork(mm, oldmm);
759+
khugepaged_fork(mm, oldmm);
763760
} else if (mpnt) {
764761
/*
765762
* The entire maple tree has already been duplicated. If the

0 commit comments

Comments
 (0)