|
|
@@ -397,6 +397,25 @@ static inline int khugepaged_test_exit(struct mm_struct *mm)
|
|
|
return atomic_read(&mm->mm_users) == 0;
|
|
|
}
|
|
|
|
|
|
+static bool hugepage_vma_check(struct vm_area_struct *vma)
|
|
|
+{
|
|
|
+ if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
|
|
|
+ (vma->vm_flags & VM_NOHUGEPAGE) ||
|
|
|
+ test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
|
|
|
+ return false;
|
|
|
+ if (shmem_file(vma->vm_file)) {
|
|
|
+ if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
|
|
|
+ return false;
|
|
|
+ return IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
|
|
|
+ HPAGE_PMD_NR);
|
|
|
+ }
|
|
|
+ if (!vma->anon_vma || vma->vm_ops)
|
|
|
+ return false;
|
|
|
+ if (is_vma_temporary_stack(vma))
|
|
|
+ return false;
|
|
|
+ return !(vma->vm_flags & VM_NO_KHUGEPAGED);
|
|
|
+}
|
|
|
+
|
|
|
int __khugepaged_enter(struct mm_struct *mm)
|
|
|
{
|
|
|
struct mm_slot *mm_slot;
|
|
|
@@ -434,15 +453,14 @@ int khugepaged_enter_vma_merge(struct vm_area_struct *vma,
|
|
|
unsigned long vm_flags)
|
|
|
{
|
|
|
unsigned long hstart, hend;
|
|
|
- if (!vma->anon_vma)
|
|
|
- /*
|
|
|
- * Not yet faulted in so we will register later in the
|
|
|
- * page fault if needed.
|
|
|
- */
|
|
|
- return 0;
|
|
|
- if (vma->vm_ops || (vm_flags & VM_NO_KHUGEPAGED))
|
|
|
- /* khugepaged not yet working on file or special mappings */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * khugepaged does not yet work on non-shmem files or special
|
|
|
+ * mappings. And file-private shmem THP is not supported.
|
|
|
+ */
|
|
|
+ if (!hugepage_vma_check(vma))
|
|
|
return 0;
|
|
|
+
|
|
|
hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
|
|
|
hend = vma->vm_end & HPAGE_PMD_MASK;
|
|
|
if (hstart < hend)
|
|
|
@@ -819,25 +837,6 @@ khugepaged_alloc_page(struct page **hpage, gfp_t gfp, int node)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-static bool hugepage_vma_check(struct vm_area_struct *vma)
|
|
|
-{
|
|
|
- if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
|
|
|
- (vma->vm_flags & VM_NOHUGEPAGE) ||
|
|
|
- test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))
|
|
|
- return false;
|
|
|
- if (shmem_file(vma->vm_file)) {
|
|
|
- if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
|
|
|
- return false;
|
|
|
- return IS_ALIGNED((vma->vm_start >> PAGE_SHIFT) - vma->vm_pgoff,
|
|
|
- HPAGE_PMD_NR);
|
|
|
- }
|
|
|
- if (!vma->anon_vma || vma->vm_ops)
|
|
|
- return false;
|
|
|
- if (is_vma_temporary_stack(vma))
|
|
|
- return false;
|
|
|
- return !(vma->vm_flags & VM_NO_KHUGEPAGED);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* If mmap_sem temporarily dropped, revalidate vma
|
|
|
* before taking mmap_sem.
|