]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/mmap: teach generic_get_unmapped_area{_topdown} to handle hugetlb mappings
authorOscar Salvador <osalvador@suse.de>
Mon, 7 Oct 2024 07:50:29 +0000 (09:50 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 1 Nov 2024 04:28:58 +0000 (21:28 -0700)
Patch series "Unify hugetlb into arch_get_unmapped_area functions", v4.

This is an attempt to get rid of a fair amount of duplicated code wrt.
hugetlb and *get_unmapped_area* functions.

HugeTLB registers a .get_unmapped_area function which gets called from
__get_unmapped_area().
hugetlb_get_unmapped_area() is defined by a bunch of architectures and
it also has a generic definition for those that do not define it.
Short-long story is that there is a ton of duplicated code between
specific hugetlb *_get_unmapped_area_* functions and mm-core functions,
so we can do better by teaching arch_get_unmapped_area* functions how
to deal with hugetlb mappings.

Note that not a lot of things need to be taught though.
hugetlb_get_unmapped_area, that gets called for hugetlb mappings, runs
some sanity checks prior to calling mm_get_unmapped_area_vmflags(), so we
do not need to that down the road in the respective
{generic,arch}_get_unmapped_area* functions.

More information can be found in the respective patches.

LTP mmapstress hugetlb selftests were ran succesfully on:

This patch (of 9):

We want to stop special casing hugetlb mappings and make them go through
generic channels, so teach generic_get_unmapped_area{_topdown} to handle
those.  The main difference is that we set info.align_mask for huge
mappings.

Link: https://lkml.kernel.org/r/20241007075037.267650-1-osalvador@suse.de
Link: https://lkml.kernel.org/r/20241007075037.267650-2-osalvador@suse.de
Signed-off-by: Oscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@redhat.com>
Cc: Donet Tom <donettom@linux.ibm.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Peter Xu <peterx@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/hugetlb.h
mm/mmap.c

index e4697539b665a2639ecd72a34f7f8b56e4c77dcf..368d552e4860c30765c88703e22d6906f9390414 100644 (file)
@@ -1035,9 +1035,19 @@ void hugetlb_unregister_node(struct node *node);
  */
 bool is_raw_hwpoison_page_in_hugepage(struct page *page);
 
+static inline unsigned long huge_page_mask_align(struct file *file)
+{
+       return PAGE_MASK & ~huge_page_mask(hstate_file(file));
+}
+
 #else  /* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 
+static inline unsigned long huge_page_mask_align(struct file *file)
+{
+       return 0;
+}
+
 static inline struct hugepage_subpool *hugetlb_folio_subpool(struct folio *folio)
 {
        return NULL;
index 79d541f1502b22eb8279c1a7ec96f37583efa7e6..fb91b2cb556156f97476a0bfb5aa556c11fb315f 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -776,6 +776,8 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
        info.low_limit = mm->mmap_base;
        info.high_limit = mmap_end;
        info.start_gap = stack_guard_placement(vm_flags);
+       if (filp && is_file_hugepages(filp))
+               info.align_mask = huge_page_mask_align(filp);
        return vm_unmapped_area(&info);
 }
 
@@ -826,6 +828,8 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
        info.low_limit = PAGE_SIZE;
        info.high_limit = arch_get_mmap_base(addr, mm->mmap_base);
        info.start_gap = stack_guard_placement(vm_flags);
+       if (filp && is_file_hugepages(filp))
+               info.align_mask = huge_page_mask_align(filp);
        addr = vm_unmapped_area(&info);
 
        /*