diff options
author | Pawit Pornkitprasan <p.pawit@gmail.com> | 2012-11-20 19:27:29 +0700 |
---|---|---|
committer | Pawit Pornkitprasan <p.pawit@gmail.com> | 2012-11-20 19:27:29 +0700 |
commit | cc7f0ca4b92d7da9d3a7bd674bfd454cc69e7780 (patch) | |
tree | 6ffdbe4122642c18f7dbf3eecd93794d49987dcb /mm/rmap.c | |
parent | 67196921fba94cf21b6c2de7da422d536fc9471d (diff) | |
parent | 89d2d133c6947c04a8ab539b997f266535beaafe (diff) | |
download | kernel_samsung_aries-cc7f0ca4b92d7da9d3a7bd674bfd454cc69e7780.zip kernel_samsung_aries-cc7f0ca4b92d7da9d3a7bd674bfd454cc69e7780.tar.gz kernel_samsung_aries-cc7f0ca4b92d7da9d3a7bd674bfd454cc69e7780.tar.bz2 |
Merge 3.0.52
Merge branch 'linux-3.0.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into jellybean-next
Conflicts:
drivers/net/tun.c
kernel/time/timekeeping.c
Change-Id: Iba7fc59ca05114d9e7bade8dfc5bb45229ebf075
Diffstat (limited to 'mm/rmap.c')
-rw-r--r-- | mm/rmap.c | 21 |
1 files changed, 16 insertions, 5 deletions
@@ -57,6 +57,7 @@ #include <linux/mmu_notifier.h> #include <linux/migrate.h> #include <linux/hugetlb.h> +#include <linux/backing-dev.h> #include <asm/tlbflush.h> @@ -936,11 +937,8 @@ int page_mkclean(struct page *page) if (page_mapped(page)) { struct address_space *mapping = page_mapping(page); - if (mapping) { + if (mapping) ret = page_mkclean_file(mapping, page); - if (page_test_and_clear_dirty(page_to_pfn(page), 1)) - ret = 1; - } } return ret; @@ -1121,6 +1119,8 @@ void page_add_file_rmap(struct page *page) */ void page_remove_rmap(struct page *page) { + struct address_space *mapping = page_mapping(page); + /* page still mapped by someone else? */ if (!atomic_add_negative(-1, &page->_mapcount)) return; @@ -1131,8 +1131,19 @@ void page_remove_rmap(struct page *page) * this if the page is anon, so about to be freed; but perhaps * not if it's in swapcache - there might be another pte slot * containing the swap entry, but page not yet written to swap. + * + * And we can skip it on file pages, so long as the filesystem + * participates in dirty tracking; but need to catch shm and tmpfs + * and ramfs pages which have been modified since creation by read + * fault. + * + * Note that mapping must be decided above, before decrementing + * mapcount (which luckily provides a barrier): once page is unmapped, + * it could be truncated and page->mapping reset to NULL at any moment. + * Note also that we are relying on page_mapping(page) to set mapping + * to &swapper_space when PageSwapCache(page). */ - if ((!PageAnon(page) || PageSwapCache(page)) && + if (mapping && !mapping_cap_account_dirty(mapping) && page_test_and_clear_dirty(page_to_pfn(page), 1)) set_page_dirty(page); /* |