|
@@ -1848,10 +1848,21 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
|
* not dirty accountable.
|
|
* not dirty accountable.
|
|
*/
|
|
*/
|
|
if (PageAnon(old_page)) {
|
|
if (PageAnon(old_page)) {
|
|
- if (trylock_page(old_page)) {
|
|
|
|
- reuse = can_share_swap_page(old_page);
|
|
|
|
- unlock_page(old_page);
|
|
|
|
|
|
+ if (!trylock_page(old_page)) {
|
|
|
|
+ page_cache_get(old_page);
|
|
|
|
+ pte_unmap_unlock(page_table, ptl);
|
|
|
|
+ lock_page(old_page);
|
|
|
|
+ page_table = pte_offset_map_lock(mm, pmd, address,
|
|
|
|
+ &ptl);
|
|
|
|
+ if (!pte_same(*page_table, orig_pte)) {
|
|
|
|
+ unlock_page(old_page);
|
|
|
|
+ page_cache_release(old_page);
|
|
|
|
+ goto unlock;
|
|
|
|
+ }
|
|
|
|
+ page_cache_release(old_page);
|
|
}
|
|
}
|
|
|
|
+ reuse = can_share_swap_page(old_page);
|
|
|
|
+ unlock_page(old_page);
|
|
} else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
|
|
} else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
|
|
(VM_WRITE|VM_SHARED))) {
|
|
(VM_WRITE|VM_SHARED))) {
|
|
/*
|
|
/*
|