--- v6
+++ v2
@@ -1,71 +1,69 @@
-migrate_misplaced_page() is only called during the page fault handling so
-it's better to pass the pointer to the struct vm_fault instead of the vma.
+The current maybe_mkwrite() is getting passed the pointer to the vma
+structure to fetch the vm_flags field.
-This way during the speculative page fault path the saved vma->vm_flags
-could be used.
+When dealing with the speculative page fault handler, it will be better to
+rely on the cached vm_flags value stored in the vm_fault structure.
+
+This patch introduce a __maybe_mkwrite() service which can be called by
+passing the value of the vm_flags field.
+
+There is no change functional changes expected for the other callers of
+maybe_mkwrite().
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
---
- include/linux/migrate.h | 4 ++--
- mm/memory.c | 2 +-
- mm/migrate.c | 4 ++--
- 3 files changed, 5 insertions(+), 5 deletions(-)
+ include/linux/mm.h | 9 +++++++--
+ mm/memory.c | 6 +++---
+ 2 files changed, 10 insertions(+), 5 deletions(-)
-diff --git a/include/linux/migrate.h b/include/linux/migrate.h
-index 0c6fe904bc97..08960ec74246 100644
---- a/include/linux/migrate.h
-+++ b/include/linux/migrate.h
-@@ -126,14 +126,14 @@ static inline void __ClearPageMovable(struct page *page)
- #ifdef CONFIG_NUMA_BALANCING
- extern bool pmd_trans_migrating(pmd_t pmd);
- extern int migrate_misplaced_page(struct page *page,
-- struct vm_area_struct *vma, int node);
-+ struct vm_fault *vmf, int node);
- #else
- static inline bool pmd_trans_migrating(pmd_t pmd)
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 43d313ff3a5b..0f4ddd72b172 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -668,13 +668,18 @@ void free_compound_page(struct page *page);
+ * pte_mkwrite. But get_user_pages can cause write faults for mappings
+ * that do not have writing enabled, when used by access_process_vm.
+ */
+-static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
++static inline pte_t __maybe_mkwrite(pte_t pte, unsigned long vma_flags)
{
- return false;
+- if (likely(vma->vm_flags & VM_WRITE))
++ if (likely(vma_flags & VM_WRITE))
+ pte = pte_mkwrite(pte);
+ return pte;
}
- static inline int migrate_misplaced_page(struct page *page,
-- struct vm_area_struct *vma, int node)
-+ struct vm_fault *vmf, int node)
- {
- return -EAGAIN; /* can't migrate now */
- }
+
++static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
++{
++ return __maybe_mkwrite(pte, vma->vm_flags);
++}
++
+ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
+ struct page *page);
+ int finish_fault(struct vm_fault *vmf);
diff --git a/mm/memory.c b/mm/memory.c
-index 79dfd2a60224..e4c0f08b78e8 100644
+index c6b18cc87e90..ad7b6372d302 100644
--- a/mm/memory.c
+++ b/mm/memory.c
-@@ -3878,7 +3878,7 @@ static int do_numa_page(struct vm_fault *vmf)
- }
+@@ -2269,7 +2269,7 @@ static inline void wp_page_reuse(struct vm_fault *vmf)
- /* Migrate to the requested node */
-- migrated = migrate_misplaced_page(page, vma, target_nid);
-+ migrated = migrate_misplaced_page(page, vmf, target_nid);
- if (migrated) {
- page_nid = target_nid;
- flags |= TNF_MIGRATED;
-diff --git a/mm/migrate.c b/mm/migrate.c
-index 33224b92db98..6e1ae62501da 100644
---- a/mm/migrate.c
-+++ b/mm/migrate.c
-@@ -1900,7 +1900,7 @@ bool pmd_trans_migrating(pmd_t pmd)
- * node. Caller is expected to have an elevated reference count on
- * the page that will be dropped by this function before returning.
- */
--int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
-+int migrate_misplaced_page(struct page *page, struct vm_fault *vmf,
- int node)
- {
- pg_data_t *pgdat = NODE_DATA(node);
-@@ -1913,7 +1913,7 @@ int migrate_misplaced_page(struct page *page, struct vm_area_struct *vma,
- * with execute permissions as they are probably shared libraries.
- */
- if (page_mapcount(page) != 1 && page_is_file_cache(page) &&
-- (vma->vm_flags & VM_EXEC))
-+ (vmf->vma_flags & VM_EXEC))
- goto out;
-
- /*
+ flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
+ entry = pte_mkyoung(vmf->orig_pte);
+- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
++ entry = __maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
+ if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1))
+ update_mmu_cache(vma, vmf->address, vmf->pte);
+ pte_unmap_unlock(vmf->pte, vmf->ptl);
+@@ -2359,8 +2359,8 @@ static int wp_page_copy(struct vm_fault *vmf)
+ inc_mm_counter_fast(mm, MM_ANONPAGES);
+ }
+ flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
+- entry = mk_pte(new_page, vma->vm_page_prot);
+- entry = maybe_mkwrite(pte_mkdirty(entry), vma);
++ entry = mk_pte(new_page, vmf->vma_page_prot);
++ entry = __maybe_mkwrite(pte_mkdirty(entry), vmf->vma_flags);
+ /*
+ * Clear the pte entry and flush it first, before updating the
+ * pte with the new entry. This will avoid a race condition
--
2.7.4