aboutsummaryrefslogtreecommitdiff
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-03-20 16:06:36 +0000
committerMark Brown <broonie@kernel.org>2015-03-20 16:06:36 +0000
commitdfaa816a41e25b4524f93483fc75ff630398b3e5 (patch)
treeff7b1c05006fa3a7816b03978cb4b2fac524e2bc /mm/hugetlb.c
parent33766107687fabb800cd1b6345333ff042d7e3ef (diff)
parent47bbd44e18034d3277a29459d1f0c45e8d1c8d3e (diff)
Merge remote-tracking branch 'lsk/linux-linaro-lsk-v3.14' into linux-linaro-lsk-v3.14
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 472259b00618..c3e8660cb616 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2488,9 +2488,10 @@ again:
goto unlock;
/*
- * HWPoisoned hugepage is already unmapped and dropped reference
+ * Migrating hugepage or HWPoisoned hugepage is already
+ * unmapped and its refcount is dropped, so just clear pte here.
*/
- if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) {
+ if (unlikely(!pte_present(pte))) {
huge_pte_clear(mm, address, ptep);
goto unlock;
}
@@ -3163,7 +3164,26 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
spin_unlock(ptl);
continue;
}
- if (!huge_pte_none(huge_ptep_get(ptep))) {
+ pte = huge_ptep_get(ptep);
+ if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) {
+ spin_unlock(ptl);
+ continue;
+ }
+ if (unlikely(is_hugetlb_entry_migration(pte))) {
+ swp_entry_t entry = pte_to_swp_entry(pte);
+
+ if (is_write_migration_entry(entry)) {
+ pte_t newpte;
+
+ make_migration_entry_read(&entry);
+ newpte = swp_entry_to_pte(entry);
+ set_huge_pte_at(mm, address, ptep, newpte);
+ pages++;
+ }
+ spin_unlock(ptl);
+ continue;
+ }
+ if (!huge_pte_none(pte)) {
pte = huge_ptep_get_and_clear(mm, address, ptep);
pte = pte_mkhuge(huge_pte_modify(pte, newprot));
pte = arch_make_huge_pte(pte, vma, NULL, 0);