aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorAlex Shi <alex.shi@linaro.org>2017-05-26 12:02:47 +0800
committerAlex Shi <alex.shi@linaro.org>2017-05-26 12:02:47 +0800
commit9d92a6ee405610ce9d250307d9c81807d1bdcc33 (patch)
treeeb880868b26441f9faa12d73b2d334f6f90ae217 /mm
parentd4a181a68ad99f0a819212f9fc09690707891325 (diff)
parent6b65a8f64f4fd256ac0f6b9e97e9939ae18fc6c7 (diff)
Merge tag 'v3.18.55' into linux-linaro-lsk-v3.18
This is the 3.18.55 stable release
Diffstat (limited to 'mm')
-rw-r--r--mm/huge_memory.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 2e39d4e0ff09..8c9cbd0e4f3f 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1205,6 +1205,16 @@ out_unlock:
return ret;
}
+/*
+ * FOLL_FORCE can write to even unwritable pmd's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pmd(pmd_t pmd, unsigned int flags)
+{
+ return pmd_write(pmd) ||
+ ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pmd_dirty(pmd));
+}
+
struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
@@ -1215,7 +1225,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
assert_spin_locked(pmd_lockptr(mm, pmd));
- if (flags & FOLL_WRITE && !pmd_write(*pmd))
+ if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, flags))
goto out;
/* Avoid dumping huge zero page */