]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mm: huge_memory: add vma_thp_disabled() and thp_disabled_by_hw()
authorKefeng Wang <wangkefeng.wang@huawei.com>
Fri, 11 Oct 2024 10:24:44 +0000 (12:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Nov 2024 01:02:32 +0000 (02:02 +0100)
[ Upstream commit 963756aac1f011d904ddd9548ae82286d3a91f96 ]

Patch series "mm: don't install PMD mappings when THPs are disabled by the
hw/process/vma".

During testing, it was found that we can get PMD mappings in processes
where THP (and more precisely, PMD mappings) are supposed to be disabled.
While it works as expected for anon+shmem, the pagecache is the
problematic bit.

For s390 KVM this currently means that a VM backed by a file located on
filesystem with large folio support can crash when KVM tries accessing the
problematic page, because the readahead logic might decide to use a
PMD-sized THP and faulting it into the page tables will install a PMD
mapping, something that s390 KVM cannot tolerate.

This might also be a problem with HW that does not support PMD mappings,
but I did not try reproducing it.

Fix it by respecting the ways to disable THPs when deciding whether we can
install a PMD mapping.  khugepaged should already be taking care of not
collapsing if THPs are effectively disabled for the hw/process/vma.

This patch (of 2):

Add vma_thp_disabled() and thp_disabled_by_hw() helpers to be shared by
shmem_allowable_huge_orders() and __thp_vma_allowable_orders().

[david@redhat.com: rename to vma_thp_disabled(), split out thp_disabled_by_hw() ]
Link: https://lkml.kernel.org/r/20241011102445.934409-2-david@redhat.com
Fixes: 793917d997df ("mm/readahead: Add large folio readahead")
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Reported-by: Leo Fu <bfu@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Cc: Boqiao Fu <bfu@redhat.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 2b0f922323cc ("mm: don't install PMD mappings when THPs are disabled by the hw/process/vma")
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/linux/huge_mm.h
mm/huge_memory.c
mm/shmem.c

index e25d9ebfdf89aabdf86dd44bd7a187903290894f..6d334c211176c0c17ba7fd653c534f5695e7be86 100644 (file)
@@ -308,6 +308,24 @@ static inline void count_mthp_stat(int order, enum mthp_stat_item item)
        (transparent_hugepage_flags &                                   \
         (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))
 
+static inline bool vma_thp_disabled(struct vm_area_struct *vma,
+               unsigned long vm_flags)
+{
+       /*
+        * Explicitly disabled through madvise or prctl, or some
+        * architectures may disable THP for some mappings, for
+        * example, s390 kvm.
+        */
+       return (vm_flags & VM_NOHUGEPAGE) ||
+              test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags);
+}
+
+static inline bool thp_disabled_by_hw(void)
+{
+       /* If the hardware/firmware marked hugepage support disabled. */
+       return transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED);
+}
+
 unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
                unsigned long len, unsigned long pgoff, unsigned long flags);
 unsigned long thp_get_unmapped_area_vmflags(struct file *filp, unsigned long addr,
index d12ec1c8c7f07e71f1688f9f732a5c29353a00be..e44508e46e89798e838afd710e1a3d7b2855d456 100644 (file)
@@ -106,18 +106,7 @@ unsigned long __thp_vma_allowable_orders(struct vm_area_struct *vma,
        if (!vma->vm_mm)                /* vdso */
                return 0;
 
-       /*
-        * Explicitly disabled through madvise or prctl, or some
-        * architectures may disable THP for some mappings, for
-        * example, s390 kvm.
-        * */
-       if ((vm_flags & VM_NOHUGEPAGE) ||
-           test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
-               return 0;
-       /*
-        * If the hardware/firmware marked hugepage support disabled.
-        */
-       if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED))
+       if (thp_disabled_by_hw() || vma_thp_disabled(vma, vm_flags))
                return 0;
 
        /* khugepaged doesn't collapse DAX vma, but page fault is fine. */
index a332323eea0b9fc432b8b82aa70b355e06ee77ca..27f496d6e43eb6f326323c70ad5ade6d4e1835ff 100644 (file)
@@ -1642,12 +1642,7 @@ unsigned long shmem_allowable_huge_orders(struct inode *inode,
        loff_t i_size;
        int order;
 
-       if (vma && ((vm_flags & VM_NOHUGEPAGE) ||
-           test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags)))
-               return 0;
-
-       /* If the hardware/firmware marked hugepage support disabled. */
-       if (transparent_hugepage_flags & (1 << TRANSPARENT_HUGEPAGE_UNSUPPORTED))
+       if (thp_disabled_by_hw() || (vma && vma_thp_disabled(vma, vm_flags)))
                return 0;
 
        global_huge = shmem_huge_global_enabled(inode, index, shmem_huge_force,