mm: prevent endless growth of anon_vma hierarchy
Subsystems (2)
PATCH v4 1/1 mm: prevent endless growth of anon_vma hierarchy
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.
---
v2: update degree in anon_vma_prepare for merged anon_vma
v3: update comment and commit message
v4: reorder anon_vma fields, update commit message, patch for current mmotm
--- include/linux/rmap.h | 10 ++++++++++ mm/rmap.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-)
include/linux/rmap.h +10 -0
@@ -37,6 +37,16 @@ struct anon_vma {atomic_t refcount;/* +* Count of child anon_vmas and VMAs which points to this anon_vma. +* +* This counter is used for making decision about reusing anon_vma +* instead of forking new one. See comments in function anon_vma_clone. +*/ +unsigned degree; + +struct anon_vma *parent;/* Parent of this anon_vma */ + +/* * NOTE: the LSB of the rb_root.rb_node is set by * mm_take_all_locks() _after_ taking the above lock. So the * rb_root must only be read/written after taking the above lock
mm/rmap.c +40 -1
107 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
mm/rmap.c static inline void unlock_anon_vma_root(struct anon_vma *root) · line 249
Quoted 11 lines · Konstantin Khlebnikov
mm/rmap.c +7
-0@@ -236,6 +240,13 @@ static inline void unlock_anon_vma_root(struct anon_vma *root)/* * Attach the anon_vmas from src to dst. * Returns 0 on success, -ENOMEM on failure. +* +* If dst->anon_vma is NULL this function tries to find and reuse existing +* anon_vma which has no vmas and only one child anon_vma. This prevents +* degradation of anon_vma hierarchy to endless linear chain in case of +* constantly forking task. In other hand anon_vma with more than one child +* isn't reused even if was no alive vma, thus rmap walker has a good chance +* to avoid scanning whole hieraryhy when it searches where page is mapped.
^^^^^^^^^
hierarchyOther than that:
Thanks for fixing this long standing issue, Konstantin.