aboutsummaryrefslogtreecommitdiffstats
path: root/mm/huge_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r--mm/huge_memory.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index fce667c0281d..004c9c2aac78 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1389,7 +1389,8 @@ out:
1389 return ret; 1389 return ret;
1390} 1390}
1391 1391
1392int hugepage_madvise(unsigned long *vm_flags, int advice) 1392int hugepage_madvise(struct vm_area_struct *vma,
1393 unsigned long *vm_flags, int advice)
1393{ 1394{
1394 switch (advice) { 1395 switch (advice) {
1395 case MADV_HUGEPAGE: 1396 case MADV_HUGEPAGE:
@@ -1404,6 +1405,13 @@ int hugepage_madvise(unsigned long *vm_flags, int advice)
1404 return -EINVAL; 1405 return -EINVAL;
1405 *vm_flags &= ~VM_NOHUGEPAGE; 1406 *vm_flags &= ~VM_NOHUGEPAGE;
1406 *vm_flags |= VM_HUGEPAGE; 1407 *vm_flags |= VM_HUGEPAGE;
1408 /*
1409 * If the vma become good for khugepaged to scan,
1410 * register it here without waiting a page fault that
1411 * may not happen any time soon.
1412 */
1413 if (unlikely(khugepaged_enter_vma_merge(vma)))
1414 return -ENOMEM;
1407 break; 1415 break;
1408 case MADV_NOHUGEPAGE: 1416 case MADV_NOHUGEPAGE:
1409 /* 1417 /*
@@ -1417,6 +1425,11 @@ int hugepage_madvise(unsigned long *vm_flags, int advice)
1417 return -EINVAL; 1425 return -EINVAL;
1418 *vm_flags &= ~VM_HUGEPAGE; 1426 *vm_flags &= ~VM_HUGEPAGE;
1419 *vm_flags |= VM_NOHUGEPAGE; 1427 *vm_flags |= VM_NOHUGEPAGE;
1428 /*
1429 * Setting VM_NOHUGEPAGE will prevent khugepaged from scanning
1430 * this vma even if we leave the mm registered in khugepaged if
1431 * it got registered before VM_NOHUGEPAGE was set.
1432 */
1420 break; 1433 break;
1421 } 1434 }
1422 1435
@@ -1784,7 +1797,8 @@ static void collapse_huge_page(struct mm_struct *mm,
1784 if (address < hstart || address + HPAGE_PMD_SIZE > hend) 1797 if (address < hstart || address + HPAGE_PMD_SIZE > hend)
1785 goto out; 1798 goto out;
1786 1799
1787 if (!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) 1800 if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) ||
1801 (vma->vm_flags & VM_NOHUGEPAGE))
1788 goto out; 1802 goto out;
1789 1803
1790 /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ 1804 /* VM_PFNMAP vmas may have vm_ops null but vm_file set */
@@ -2007,8 +2021,9 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages,
2007 break; 2021 break;
2008 } 2022 }
2009 2023
2010 if (!(vma->vm_flags & VM_HUGEPAGE) && 2024 if ((!(vma->vm_flags & VM_HUGEPAGE) &&
2011 !khugepaged_always()) { 2025 !khugepaged_always()) ||
2026 (vma->vm_flags & VM_NOHUGEPAGE)) {
2012 progress++; 2027 progress++;
2013 continue; 2028 continue;
2014 } 2029 }