diff options
author | KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> | 2008-10-18 23:28:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 11:52:38 -0400 |
commit | b7abea9630bc8ffc663a751e46680db25c4cdf8d (patch) | |
tree | b37d5ba073ccea31328812c74598872d49a85735 | |
parent | 073e587ec2cc377867e53d8b8959738a8e16cff6 (diff) |
memcg: make page->mapping NULL before uncharge
This patch tries to make page->mapping to be NULL before
mem_cgroup_uncharge_cache_page() is called.
"page->mapping == NULL" is a good check for "whether the page is still
radix-tree or not". This patch also adds BUG_ON() to
mem_cgroup_uncharge_cache_page();
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Reviewed-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | mm/filemap.c | 2 | ||||
-rw-r--r-- | mm/memcontrol.c | 1 | ||||
-rw-r--r-- | mm/migrate.c | 9 |
3 files changed, 9 insertions, 3 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index e1b23fda48de..ab8553658af3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -116,12 +116,12 @@ void __remove_from_page_cache(struct page *page) | |||
116 | { | 116 | { |
117 | struct address_space *mapping = page->mapping; | 117 | struct address_space *mapping = page->mapping; |
118 | 118 | ||
119 | mem_cgroup_uncharge_cache_page(page); | ||
120 | radix_tree_delete(&mapping->page_tree, page->index); | 119 | radix_tree_delete(&mapping->page_tree, page->index); |
121 | page->mapping = NULL; | 120 | page->mapping = NULL; |
122 | mapping->nrpages--; | 121 | mapping->nrpages--; |
123 | __dec_zone_page_state(page, NR_FILE_PAGES); | 122 | __dec_zone_page_state(page, NR_FILE_PAGES); |
124 | BUG_ON(page_mapped(page)); | 123 | BUG_ON(page_mapped(page)); |
124 | mem_cgroup_uncharge_cache_page(page); | ||
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Some filesystems seem to re-dirty the page even after | 127 | * Some filesystems seem to re-dirty the page even after |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index e93a4db93fbe..6f8b5b3b38b2 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -734,6 +734,7 @@ void mem_cgroup_uncharge_page(struct page *page) | |||
734 | void mem_cgroup_uncharge_cache_page(struct page *page) | 734 | void mem_cgroup_uncharge_cache_page(struct page *page) |
735 | { | 735 | { |
736 | VM_BUG_ON(page_mapped(page)); | 736 | VM_BUG_ON(page_mapped(page)); |
737 | VM_BUG_ON(page->mapping); | ||
737 | __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE); | 738 | __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE); |
738 | } | 739 | } |
739 | 740 | ||
diff --git a/mm/migrate.c b/mm/migrate.c index 11c6c56ec017..6602941bfab0 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -330,8 +330,6 @@ static int migrate_page_move_mapping(struct address_space *mapping, | |||
330 | __inc_zone_page_state(newpage, NR_FILE_PAGES); | 330 | __inc_zone_page_state(newpage, NR_FILE_PAGES); |
331 | 331 | ||
332 | spin_unlock_irq(&mapping->tree_lock); | 332 | spin_unlock_irq(&mapping->tree_lock); |
333 | if (!PageSwapCache(newpage)) | ||
334 | mem_cgroup_uncharge_cache_page(page); | ||
335 | 333 | ||
336 | return 0; | 334 | return 0; |
337 | } | 335 | } |
@@ -341,6 +339,8 @@ static int migrate_page_move_mapping(struct address_space *mapping, | |||
341 | */ | 339 | */ |
342 | static void migrate_page_copy(struct page *newpage, struct page *page) | 340 | static void migrate_page_copy(struct page *newpage, struct page *page) |
343 | { | 341 | { |
342 | int anon; | ||
343 | |||
344 | copy_highpage(newpage, page); | 344 | copy_highpage(newpage, page); |
345 | 345 | ||
346 | if (PageError(page)) | 346 | if (PageError(page)) |
@@ -378,8 +378,13 @@ static void migrate_page_copy(struct page *newpage, struct page *page) | |||
378 | #endif | 378 | #endif |
379 | ClearPagePrivate(page); | 379 | ClearPagePrivate(page); |
380 | set_page_private(page, 0); | 380 | set_page_private(page, 0); |
381 | /* page->mapping contains a flag for PageAnon() */ | ||
382 | anon = PageAnon(page); | ||
381 | page->mapping = NULL; | 383 | page->mapping = NULL; |
382 | 384 | ||
385 | if (!anon) /* This page was removed from radix-tree. */ | ||
386 | mem_cgroup_uncharge_cache_page(page); | ||
387 | |||
383 | /* | 388 | /* |
384 | * If any waiters have accumulated on the new page then | 389 | * If any waiters have accumulated on the new page then |
385 | * wake them up. | 390 | * wake them up. |