diff options
author | Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> | 2009-05-28 17:34:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-05-29 11:40:02 -0400 |
commit | e767e0561d7fd2333df1921f1ab4176211f9036b (patch) | |
tree | 3b936733f80ceb1ee61ce99f927d002d2296250e /include/linux/swap.h | |
parent | bd6daba909d8484bd2ccf6017db4028d7a420927 (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 'include/linux/swap.h')
-rw-r--r-- | include/linux/swap.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/include/linux/swap.h b/include/linux/swap.h index 62d81435347a..d476aad3ff57 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
@@ -437,6 +437,11 @@ static inline int mem_cgroup_cache_charge_swapin(struct page *page, | |||
437 | return 0; | 437 | return 0; |
438 | } | 438 | } |
439 | 439 | ||
440 | static inline void | ||
441 | mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent) | ||
442 | { | ||
443 | } | ||
444 | |||
440 | #endif /* CONFIG_SWAP */ | 445 | #endif /* CONFIG_SWAP */ |
441 | #endif /* __KERNEL__*/ | 446 | #endif /* __KERNEL__*/ |
442 | #endif /* _LINUX_SWAP_H */ | 447 | #endif /* _LINUX_SWAP_H */ |