• Leon Yu's avatar
    mm: fix anon_vma->degree underflow in anon_vma endless growing prevention · 3fe89b3e
    Leon Yu authored
    I have constantly stumbled upon "kernel BUG at mm/rmap.c:399!" after
    upgrading to 3.19 and had no luck with 4.0-rc1 neither.
    
    So, after looking into new logic introduced by commit 7a3ef208 ("mm:
    prevent endless growth of anon_vma hierarchy"), I found chances are that
    unlink_anon_vmas() is called without incrementing dst->anon_vma->degree
    in anon_vma_clone() due to allocation failure.  If dst->anon_vma is not
    NULL in error path, its degree will be incorrectly decremented in
    unlink_anon_vmas() and eventually underflow when exiting as a result of
    another call to unlink_anon_vmas().  That's how "kernel BUG at
    mm/rmap.c:399!" is triggered for me.
    
    This patch fixes the underflow by dropping dst->anon_vma when allocation
    fails.  It's safe to do so regardless of original value of dst->anon_vma
    because dst->anon_vma doesn't have valid meaning if anon_vma_clone()
    fails.  Besides, callers don't care dst->anon_vma in such case neither.
    
    Also suggested by Michal Hocko, we can clean up vma_adjust() a bit as
    anon_vma_clone() now does the work.
    
    [akpm@linux-foundation.org: tweak comment]
    Fixes: 7a3ef208 ("mm: prevent endless growth of anon_vma hierarchy")
    Signed-off-by: 's avatarLeon Yu <chianglungyu@gmail.com>
    Signed-off-by: 's avatarKonstantin Khlebnikov <koct9i@gmail.com>
    Reviewed-by: 's avatarMichal Hocko <mhocko@suse.cz>
    Acked-by: 's avatarRik van Riel <riel@redhat.com>
    Acked-by: 's avatarDavid Rientjes <rientjes@google.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: 's avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: 's avatarLinus Torvalds <torvalds@linux-foundation.org>
    3fe89b3e
rmap.c 43.5 KB