|
@@ -2066,7 +2066,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
|
{
|
|
|
struct page *old_page, *new_page = NULL;
|
|
|
pte_t entry;
|
|
|
- int ret = 0;
|
|
|
+ int page_copied = 0;
|
|
|
unsigned long mmun_start = 0; /* For mmu_notifiers */
|
|
|
unsigned long mmun_end = 0; /* For mmu_notifiers */
|
|
|
struct mem_cgroup *memcg;
|
|
@@ -2101,7 +2101,9 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
|
&ptl);
|
|
|
if (!pte_same(*page_table, orig_pte)) {
|
|
|
unlock_page(old_page);
|
|
|
- goto unlock;
|
|
|
+ pte_unmap_unlock(page_table, ptl);
|
|
|
+ page_cache_release(old_page);
|
|
|
+ return 0;
|
|
|
}
|
|
|
page_cache_release(old_page);
|
|
|
}
|
|
@@ -2148,7 +2150,9 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
|
&ptl);
|
|
|
if (!pte_same(*page_table, orig_pte)) {
|
|
|
unlock_page(old_page);
|
|
|
- goto unlock;
|
|
|
+ pte_unmap_unlock(page_table, ptl);
|
|
|
+ page_cache_release(old_page);
|
|
|
+ return 0;
|
|
|
}
|
|
|
page_mkwrite = 1;
|
|
|
}
|
|
@@ -2246,29 +2250,28 @@ gotten:
|
|
|
|
|
|
/* Free the old page.. */
|
|
|
new_page = old_page;
|
|
|
- ret |= VM_FAULT_WRITE;
|
|
|
+ page_copied = 1;
|
|
|
} else
|
|
|
mem_cgroup_cancel_charge(new_page, memcg);
|
|
|
|
|
|
if (new_page)
|
|
|
page_cache_release(new_page);
|
|
|
-unlock:
|
|
|
+
|
|
|
pte_unmap_unlock(page_table, ptl);
|
|
|
- if (mmun_end > mmun_start)
|
|
|
- mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
|
|
|
+ mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
|
|
|
if (old_page) {
|
|
|
/*
|
|
|
* Don't let another task, with possibly unlocked vma,
|
|
|
* keep the mlocked page.
|
|
|
*/
|
|
|
- if ((ret & VM_FAULT_WRITE) && (vma->vm_flags & VM_LOCKED)) {
|
|
|
+ if (page_copied && (vma->vm_flags & VM_LOCKED)) {
|
|
|
lock_page(old_page); /* LRU manipulation */
|
|
|
munlock_vma_page(old_page);
|
|
|
unlock_page(old_page);
|
|
|
}
|
|
|
page_cache_release(old_page);
|
|
|
}
|
|
|
- return ret;
|
|
|
+ return page_copied ? VM_FAULT_WRITE : 0;
|
|
|
oom_free_new:
|
|
|
page_cache_release(new_page);
|
|
|
oom:
|