mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-09 02:51:11 +01:00
mm/rmap.c: reuse mergeable anon_vma as parent when fork
In __anon_vma_prepare(), we will try to find anon_vma if it is possible to reuse it. While on fork, the logic is different. Since commit5beb493052("mm: change anon_vma linking to fix multi-process server scalability issue"), function anon_vma_clone() tries to allocate new anon_vma for child process. But the logic here will allocate a new anon_vma for each vma, even in parent this vma is mergeable and share the same anon_vma with its sibling. This may do better for scalability issue, while it is not necessary to do so especially after interval tree is used. Commit7a3ef208e6("mm: prevent endless growth of anon_vma hierarchy") tries to reuse some anon_vma by counting child anon_vma and attached vmas. While for those mergeable anon_vmas, we can just reuse it and not necessary to go through the logic. After this change, kernel build test reduces 20% anon_vma allocation. Do the same kernel build test, it shows run time in sys reduced 11.6%. Origin: real 2m50.467s user 17m52.002s sys 1m51.953s real 2m48.662s user 17m55.464s sys 1m50.553s real 2m51.143s user 17m59.687s sys 1m53.600s Patched: real 2m39.933s user 17m1.835s sys 1m38.802s real 2m39.321s user 17m1.634s sys 1m39.206s real 2m39.575s user 17m1.420s sys 1m38.845s Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Wei Yang <[email protected]> Acked-by: Konstantin Khlebnikov <[email protected]> Cc: Kirill A. Shutemov <[email protected]> Cc: "Jérôme Glisse" <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Qian Cai <[email protected]> Cc: Shakeel Butt <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
1 parent
47b390d23b
commit
4e4a9eb921
1 file changed
+13
@@ -269,6 +269,19 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
|
||||
{
|
||||
struct anon_vma_chain *avc, *pavc;
|
||||
struct anon_vma *root = NULL;
|
||||
struct vm_area_struct *prev = dst->vm_prev, *pprev = src->vm_prev;
|
||||
|
||||
/*
|
||||
* If parent share anon_vma with its vm_prev, keep this sharing in in
|
||||
* child.
|
||||
*
|
||||
* 1. Parent has vm_prev, which implies we have vm_prev.
|
||||
* 2. Parent and its vm_prev have the same anon_vma.
|
||||
*/
|
||||
if (!dst->anon_vma && src->anon_vma &&
|
||||
pprev && pprev->anon_vma == src->anon_vma)
|
||||
dst->anon_vma = prev->anon_vma;
|
||||
|
||||
|
||||
list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
|
||||
struct anon_vma *anon_vma;
|
||||
|
||||
Reference in new issue
Block a user