Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 98385
b: refs/heads/master
c: 945754a
h: refs/heads/master
i:
  98383: 826bc78
v: v3
  • Loading branch information
Nick Piggin authored and Linus Torvalds committed Jun 23, 2008
1 parent 451783d commit d32e10d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 672ca28e300c17bf8d792a2a7a8631193e580c74
refs/heads/master: 945754a1754f9d4c2974a8241ad4f92fad7f3a6a
27 changes: 26 additions & 1 deletion trunk/mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1785,7 +1785,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
if (likely(pte_same(*page_table, orig_pte))) {
if (old_page) {
page_remove_rmap(old_page, vma);
if (!PageAnon(old_page)) {
dec_mm_counter(mm, file_rss);
inc_mm_counter(mm, anon_rss);
Expand All @@ -1807,6 +1806,32 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
lru_cache_add_active(new_page);
page_add_new_anon_rmap(new_page, vma, address);

if (old_page) {
/*
* Only after switching the pte to the new page may
* we remove the mapcount here. Otherwise another
* process may come and find the rmap count decremented
* before the pte is switched to the new page, and
* "reuse" the old page writing into it while our pte
* here still points into it and can be read by other
* threads.
*
* The critical issue is to order this
* page_remove_rmap with the ptp_clear_flush above.
* Those stores are ordered by (if nothing else,)
* the barrier present in the atomic_add_negative
* in page_remove_rmap.
*
* Then the TLB flush in ptep_clear_flush ensures that
* no process can access the old page before the
* decremented mapcount is visible. And the old page
* cannot be reused until after the decremented
* mapcount is visible. So transitively, TLBs to
* old page will be flushed before it can be reused.
*/
page_remove_rmap(old_page, vma);
}

/* Free the old page.. */
new_page = old_page;
ret |= VM_FAULT_WRITE;
Expand Down

0 comments on commit d32e10d

Please sign in to comment.