Skip to content

Commit

Permalink
mm: thp: register mm for khugepaged when merging vma for shmem
Browse files Browse the repository at this point in the history
When merging anonymous page vma, if the size of the vma can fit in at
least one hugepage, the mm will be registered for khugepaged for
collapsing THP in the future.

But it skips shmem vmas.  Do so for shmem also, but not for file-private
mappings when merging a vma in order to increase the odds of collapsing a
hugepage via khugepaged.

hugepage_vma_check() sounds like a good fit to do the check.  And move the
definition of it before khugepaged_enter_vma_merge() to avoid a build
error.

Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Yang Shi <[email protected]>
Acked-by: Kirill A. Shutemov <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
Yang Shi authored and hnaz committed Jun 23, 2018
1 parent 4343f62 commit 02b75dc
Showing 1 changed file with 26 additions and 27 deletions.
53 changes: 26 additions & 27 deletions mm/khugepaged.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 02b75dc

Please sign in to comment.