• Ryan Roberts's avatar
    mm: thp_get_unmapped_area must honour topdown preference · 96204e15
    Ryan Roberts authored
    The addition of commit efa7df3e ("mm: align larger anonymous mappings
    on THP boundaries") caused the "virtual_address_range" mm selftest to
    start failing on arm64.  Let's fix that regression.
    
    There were 2 visible problems when running the test; 1) it takes much
    longer to execute, and 2) the test fails.  Both are related:
    
    The (first part of the) test allocates as many 1GB anonymous blocks as it
    can in the low 256TB of address space, passing NULL as the addr hint to
    mmap.  Before the faulty patch, all allocations were abutted and contained
    in a single, merged VMA.  However, after this patch, each allocation is in
    its own VMA, and there is a 2M gap between each VMA.  This causes the 2
    problems in the test: 1) mmap becomes MUCH slower because there are so
    many VMAs to check to find a new 1G gap.  2) mmap fails once it hits the
    VMA limit (/proc/sys/vm/max_map_count).  Hitting this limit then causes a
    subsequent calloc() to fail, which causes the test to fail.
    
    The problem is that arm64 (unlike x86) selects
    ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT.  But __thp_get_unmapped_area()
    allocates len+2M then always aligns to the bottom of the discovered gap. 
    That causes the 2M hole.
    
    Fix this by detecting cases where we can still achive the alignment goal
    when moved to the top of the allocated area, if configured to prefer
    top-down allocation.
    
    While we are at it, fix thp_get_unmapped_area's use of pgoff, which should
    always be zero for anonymous mappings.  Prior to the faulty change, while
    it was possible for user space to pass in pgoff!=0, the old
    mm->get_unmapped_area() handler would not use it.  thp_get_unmapped_area()
    does use it, so let's explicitly zero it before calling the handler.  This
    should also be the correct behavior for arches that define their own
    get_unmapped_area() handler.
    
    Link: https://lkml.kernel.org/r/20240123171420.3970220-1-ryan.roberts@arm.com
    Fixes: efa7df3e ("mm: align larger anonymous mappings on THP boundaries")
    Closes: https://lore.kernel.org/linux-mm/1e8f5ac7-54ce-433a-ae53-81522b2320e1@arm.com/Signed-off-by: default avatarRyan Roberts <ryan.roberts@arm.com>
    Reviewed-by: default avatarYang Shi <shy828301@gmail.com>
    Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
    Cc: Rik van Riel <riel@surriel.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    96204e15
mmap.c 106 KB