mm: prevent endless growth of anon_vma hierarchy
authorKonstantin Khlebnikov <koct9i@gmail.com>
Thu, 8 Jan 2015 22:32:15 +0000 (14:32 -0800)
committerSasha Levin <sasha.levin@oracle.com>
Fri, 24 Apr 2015 21:13:13 +0000 (17:13 -0400)
commit3f1618006bca4f51fd1f6766cab88bb499af06b7
treedda2f74216da13d1c3205a46c0735aeea2a3c0f1
parentf68391eb9bfd80cc898b07e71ed400d7e0c0f91a
mm: prevent endless growth of anon_vma hierarchy

[ Upstream commit 7a3ef208e662f4b63d43a23f61a64a129c525bbc ]

Constantly forking task causes unlimited grow of anon_vma chain.  Each
next child allocates new level of anon_vmas and links vma to all
previous levels because pages might be inherited from any level.

This patch adds heuristic which decides to reuse existing anon_vma
instead of forking new one.  It adds counter anon_vma->degree which
counts linked vmas and directly descending anon_vmas and reuses anon_vma
if counter is lower than two.  As a result each anon_vma has either vma
or at least two descending anon_vmas.  In such trees half of nodes are
leafs with alive vmas, thus count of anon_vmas is no more than two times
bigger than count of vmas.

This heuristic reuses anon_vmas as few as possible because each reuse
adds false aliasing among vmas and rmap walker ought to scan more ptes
when it searches where page is might be mapped.

Link: http://lkml.kernel.org/r/20120816024610.GA5350@evergreen.ssec.wisc.edu
Fixes: 5beb49305251 ("mm: change anon_vma linking to fix multi-process server scalability issue")
[akpm@linux-foundation.org: fix typo, per Rik]
Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com>
Reported-by: Daniel Forrest <dan.forrest@ssec.wisc.edu>
Tested-by: Michal Hocko <mhocko@suse.cz>
Tested-by: Jerome Marchand <jmarchan@redhat.com>
Reviewed-by: Michal Hocko <mhocko@suse.cz>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: <stable@vger.kernel.org> [2.6.34+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
include/linux/rmap.h
mm/rmap.c