diff options
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r-- | mm/huge_memory.c | 23 |
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 | ||
1392 | int hugepage_madvise(unsigned long *vm_flags, int advice) | 1392 | int 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 | } |