aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memory.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/mm/memory.c b/mm/memory.c
index dd7d7fc5ed60..65962534b4ed 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1467,11 +1467,21 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1467 goto gotten; 1467 goto gotten;
1468 1468
1469 /* 1469 /*
1470 * Only catch write-faults on shared writable pages, read-only 1470 * Take out anonymous pages first, anonymous shared vmas are
1471 * shared pages can get COWed by get_user_pages(.write=1, .force=1). 1471 * not dirty accountable.
1472 */ 1472 */
1473 if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) == 1473 if (PageAnon(old_page)) {
1474 if (!TestSetPageLocked(old_page)) {
1475 reuse = can_share_swap_page(old_page);
1476 unlock_page(old_page);
1477 }
1478 } else if (unlikely((vma->vm_flags & (VM_WRITE|VM_SHARED)) ==
1474 (VM_WRITE|VM_SHARED))) { 1479 (VM_WRITE|VM_SHARED))) {
1480 /*
1481 * Only catch write-faults on shared writable pages,
1482 * read-only shared pages can get COWed by
1483 * get_user_pages(.write=1, .force=1).
1484 */
1475 if (vma->vm_ops && vma->vm_ops->page_mkwrite) { 1485 if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
1476 /* 1486 /*
1477 * Notify the address space that the page is about to 1487 * Notify the address space that the page is about to
@@ -1503,9 +1513,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1503 dirty_page = old_page; 1513 dirty_page = old_page;
1504 get_page(dirty_page); 1514 get_page(dirty_page);
1505 reuse = 1; 1515 reuse = 1;
1506 } else if (PageAnon(old_page) && !TestSetPageLocked(old_page)) {
1507 reuse = can_share_swap_page(old_page);
1508 unlock_page(old_page);
1509 } 1516 }
1510 1517
1511 if (reuse) { 1518 if (reuse) {