aboutsummaryrefslogtreecommitdiffstats
path: root/mm/rmap.c
diff options
context:
space:
mode:
authorBalbir Singh <balbir@linux.vnet.ibm.com>2008-02-07 03:13:53 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:18 -0500
commit8a9f3ccd24741b50200c3f33d62534c7271f3dfc (patch)
tree066aabd8d2952299501f067a91cbfd6f47ee62f6 /mm/rmap.c
parent78fb74669e80883323391090e4d26d17fe29488f (diff)
Memory controller: memory accounting
Add the accounting hooks. The accounting is carried out for RSS and Page Cache (unmapped) pages. There is now a common limit and accounting for both. The RSS accounting is accounted at page_add_*_rmap() and page_remove_rmap() time. Page cache is accounted at add_to_page_cache(), __delete_from_page_cache(). Swap cache is also accounted for. Each page's page_cgroup is protected with the last bit of the page_cgroup pointer, this makes handling of race conditions involving simultaneous mappings of a page easier. A reference count is kept in the page_cgroup to deal with cases where a page might be unmapped from the RSS of all tasks, but still lives in the page cache. Credits go to Vaidyanathan Srinivasan for helping with reference counting work of the page cgroup. Almost all of the page cache accounting code has help from Vaidyanathan Srinivasan. [hugh@veritas.com: fix swapoff breakage] [akpm@linux-foundation.org: fix locking] Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com> Cc: Pavel Emelianov <xemul@openvz.org> Cc: Paul Menage <menage@google.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Kirill Korotaev <dev@sw.ru> Cc: Herbert Poetzl <herbert@13thfloor.at> Cc: David Rientjes <rientjes@google.com> Cc: <Valdis.Kletnieks@vt.edu> Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/rmap.c')
-rw-r--r--mm/rmap.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/mm/rmap.c b/mm/rmap.c
index 57ad276900c9..4a3487921eff 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -48,6 +48,7 @@
48#include <linux/rcupdate.h> 48#include <linux/rcupdate.h>
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/kallsyms.h> 50#include <linux/kallsyms.h>
51#include <linux/memcontrol.h>
51 52
52#include <asm/tlbflush.h> 53#include <asm/tlbflush.h>
53 54
@@ -554,8 +555,14 @@ void page_add_anon_rmap(struct page *page,
554 VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end); 555 VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
555 if (atomic_inc_and_test(&page->_mapcount)) 556 if (atomic_inc_and_test(&page->_mapcount))
556 __page_set_anon_rmap(page, vma, address); 557 __page_set_anon_rmap(page, vma, address);
557 else 558 else {
558 __page_check_anon_rmap(page, vma, address); 559 __page_check_anon_rmap(page, vma, address);
560 /*
561 * We unconditionally charged during prepare, we uncharge here
562 * This takes care of balancing the reference counts
563 */
564 mem_cgroup_uncharge_page(page);
565 }
559} 566}
560 567
561/* 568/*
@@ -586,6 +593,12 @@ void page_add_file_rmap(struct page *page)
586{ 593{
587 if (atomic_inc_and_test(&page->_mapcount)) 594 if (atomic_inc_and_test(&page->_mapcount))
588 __inc_zone_page_state(page, NR_FILE_MAPPED); 595 __inc_zone_page_state(page, NR_FILE_MAPPED);
596 else
597 /*
598 * We unconditionally charged during prepare, we uncharge here
599 * This takes care of balancing the reference counts
600 */
601 mem_cgroup_uncharge_page(page);
589} 602}
590 603
591#ifdef CONFIG_DEBUG_VM 604#ifdef CONFIG_DEBUG_VM
@@ -646,6 +659,8 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
646 page_clear_dirty(page); 659 page_clear_dirty(page);
647 set_page_dirty(page); 660 set_page_dirty(page);
648 } 661 }
662 mem_cgroup_uncharge_page(page);
663
649 __dec_zone_page_state(page, 664 __dec_zone_page_state(page,
650 PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED); 665 PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
651 } 666 }