diff options
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r-- | mm/hugetlb.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a73dbdcb89eb..0fa9de8361bd 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -2217,6 +2217,19 @@ nomem: | |||
2217 | return -ENOMEM; | 2217 | return -ENOMEM; |
2218 | } | 2218 | } |
2219 | 2219 | ||
2220 | static int is_hugetlb_entry_migration(pte_t pte) | ||
2221 | { | ||
2222 | swp_entry_t swp; | ||
2223 | |||
2224 | if (huge_pte_none(pte) || pte_present(pte)) | ||
2225 | return 0; | ||
2226 | swp = pte_to_swp_entry(pte); | ||
2227 | if (non_swap_entry(swp) && is_migration_entry(swp)) { | ||
2228 | return 1; | ||
2229 | } else | ||
2230 | return 0; | ||
2231 | } | ||
2232 | |||
2220 | static int is_hugetlb_entry_hwpoisoned(pte_t pte) | 2233 | static int is_hugetlb_entry_hwpoisoned(pte_t pte) |
2221 | { | 2234 | { |
2222 | swp_entry_t swp; | 2235 | swp_entry_t swp; |
@@ -2648,7 +2661,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2648 | ptep = huge_pte_offset(mm, address); | 2661 | ptep = huge_pte_offset(mm, address); |
2649 | if (ptep) { | 2662 | if (ptep) { |
2650 | entry = huge_ptep_get(ptep); | 2663 | entry = huge_ptep_get(ptep); |
2651 | if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | 2664 | if (unlikely(is_hugetlb_entry_migration(entry))) { |
2665 | migration_entry_wait(mm, (pmd_t *)ptep, address); | ||
2666 | return 0; | ||
2667 | } else if (unlikely(is_hugetlb_entry_hwpoisoned(entry))) | ||
2652 | return VM_FAULT_HWPOISON; | 2668 | return VM_FAULT_HWPOISON; |
2653 | } | 2669 | } |
2654 | 2670 | ||