aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2006-09-26 02:31:00 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:44 -0400
commitee6a6457886a80415db209e87033b63f2b06558c (patch)
tree227351bf31ccc6153879cc900c5d6a822832b645
parente88dd6c11c5aef74d8b74a062767add53315533b (diff)
[PATCH] mm: fixup do_wp_page()
Wrt. the recent modifications in do_wp_page() Hugh Dickins pointed out: "I now realize it's right to the first order (normal case) and to the second order (ptrace poke), but not to the third order (ptrace poke anon page here to be COWed - perhaps can't occur without intervening mprotects)." This patch restores the old COW behaviour for anonymous pages. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-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) {