]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: make hugetlb mappings go through mm_get_unmapped_area_vmflags
authorOscar Salvador <osalvador@suse.de>
Mon, 7 Oct 2024 07:50:34 +0000 (09:50 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 1 Nov 2024 04:28:59 +0000 (21:28 -0700)
Hugetlb mappings will no longer be special cased but rather go through the
generic mm_get_unmapped_area_vmflags function.  For that to happen, let us
remove the .get_unmapped_area from hugetlbfs_file_operations struct, and
hint __get_unmapped_area that it should not send hugetlb mappings through
thp_get_unmapped_area_vmflags but through mm_get_unmapped_area_vmflags.

Create also a function called hugetlb_mmap_check_and_align() where a
couple of safety checks are being done and the addr is aligned to the huge
page size.  Otherwise we will have to do this in every single function,
which duplicates quite a lot of code.

Link: https://lkml.kernel.org/r/20241007075037.267650-7-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>
fs/hugetlbfs/inode.c
include/linux/hugetlb.h

index 5cf327337e2276e283f49cd9898216a5f721b76d..2c5f34e315d253cf563a70c2ca7abf0211fb9669 100644 (file)
@@ -258,15 +258,23 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
                        pgoff, flags);
 }
 
-#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-static unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-                         unsigned long len, unsigned long pgoff,
-                         unsigned long flags)
+unsigned long
+__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+                           unsigned long len, unsigned long flags)
 {
-       return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
+       unsigned long addr0 = 0;
+       struct hstate *h = hstate_file(file);
+
+       if (len & ~huge_page_mask(h))
+               return -EINVAL;
+       if ((flags & MAP_FIXED) && prepare_hugepage_range(file, addr, len))
+               return -EINVAL;
+       if (addr)
+               addr0 = ALIGN(addr, huge_page_size(h));
+
+       return mm_get_unmapped_area_vmflags(current->mm, file, addr, len, pgoff,
+                                           flags, 0);
 }
-#endif
 
 /*
  * Someone wants to read @bytes from a HWPOISON hugetlb @page from @offset.
@@ -1300,7 +1308,7 @@ static const struct file_operations hugetlbfs_file_operations = {
        .read_iter              = hugetlbfs_read_iter,
        .mmap                   = hugetlbfs_file_mmap,
        .fsync                  = noop_fsync,
-       .get_unmapped_area      = hugetlb_get_unmapped_area,
+       .get_unmapped_area      = __hugetlb_get_unmapped_area,
        .llseek                 = default_llseek,
        .fallocate              = hugetlbfs_fallocate,
        .fop_flags              = FOP_HUGE_PAGES,
index 368d552e4860c30765c88703e22d6906f9390414..3a81b6126f623e73b6bd427da66438b76dd5ad96 100644 (file)
@@ -546,11 +546,10 @@ static inline struct hstate *hstate_inode(struct inode *i)
 }
 #endif /* !CONFIG_HUGETLBFS */
 
-#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-                                       unsigned long len, unsigned long pgoff,
-                                       unsigned long flags);
-#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
+unsigned long
+__generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+                                   unsigned long len, unsigned long pgoff,
+                                   unsigned long flags);
 
 unsigned long
 generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,