aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/huge_memory.c23
-rw-r--r--mm/madvise.c2
2 files changed, 20 insertions, 5 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 }
diff --git a/mm/madvise.c b/mm/madvise.c
index bbac126e03ed..2221491ed503 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -73,7 +73,7 @@ static long madvise_behavior(struct vm_area_struct * vma,
73 break; 73 break;
74 case MADV_HUGEPAGE: 74 case MADV_HUGEPAGE:
75 case MADV_NOHUGEPAGE: 75 case MADV_NOHUGEPAGE:
76 error = hugepage_madvise(&new_flags, behavior); 76 error = hugepage_madvise(vma, &new_flags, behavior);
77 if (error) 77 if (error)
78 goto out; 78 goto out;
79 break; 79 break;