mirror of https://gitee.com/openkylin/linux.git
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/20191011072256.16275-2-richardw.yang@linux.intel.com Signed-off-by: Wei Yang <richardw.yang@linux.intel.com> Acked-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: "Jérôme Glisse" <jglisse@redhat.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Rik van Riel <riel@surriel.com> Cc: Qian Cai <cai@lca.pw> Cc: Shakeel Butt <shakeelb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
47b390d23b
commit
4e4a9eb921
13
mm/rmap.c
13
mm/rmap.c
|
@ -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_chain *avc, *pavc;
|
||||||
struct anon_vma *root = NULL;
|
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) {
|
list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
|
||||||
struct anon_vma *anon_vma;
|
struct anon_vma *anon_vma;
|
||||||
|
|
Loading…
Reference in New Issue