aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorDaisuke Nishimura <nishimura@mxp.nes.nec.co.jp>2009-05-28 17:34:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-05-29 11:40:02 -0400
commite767e0561d7fd2333df1921f1ab4176211f9036b (patch)
tree3b936733f80ceb1ee61ce99f927d002d2296250e /mm/memcontrol.c
parentbd6daba909d8484bd2ccf6017db4028d7a420927 (diff)
memcg: fix deadlock between lock_page_cgroup and mapping tree_lock
mapping->tree_lock can be acquired from interrupt context. Then, following dead lock can occur. Assume "A" as a page. CPU0: lock_page_cgroup(A) interrupted -> take mapping->tree_lock. CPU1: take mapping->tree_lock -> lock_page_cgroup(A) This patch tries to fix above deadlock by moving memcg's hook to out of mapping->tree_lock. charge/uncharge of pagecache/swapcache is protected by page lock, not tree_lock. After this patch, lock_page_cgroup() is not called under mapping->tree_lock. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 01c2d8f1468..4a747a27a22 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1488,8 +1488,9 @@ void mem_cgroup_uncharge_cache_page(struct page *page)
1488 __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE); 1488 __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE);
1489} 1489}
1490 1490
1491#ifdef CONFIG_SWAP
1491/* 1492/*
1492 * called from __delete_from_swap_cache() and drop "page" account. 1493 * called after __delete_from_swap_cache() and drop "page" account.
1493 * memcg information is recorded to swap_cgroup of "ent" 1494 * memcg information is recorded to swap_cgroup of "ent"
1494 */ 1495 */
1495void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent) 1496void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
@@ -1506,6 +1507,7 @@ void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
1506 if (memcg) 1507 if (memcg)
1507 css_put(&memcg->css); 1508 css_put(&memcg->css);
1508} 1509}
1510#endif
1509 1511
1510#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP 1512#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
1511/* 1513/*