Messages in this thread | | | Date | Tue, 26 May 2009 12:12:59 +0900 | From | KAMEZAWA Hiroyuki <> | Subject | [RFC][PATCH] memcg: fix swap account (26/May)[0/5] |
| |
As Nishimura reported, there is a race at handling swap cache.
Typical cases are following (from Nishimura's mail)
== Type-1 == If some pages of processA has been swapped out, it calls free_swap_and_cache(). And if at the same time, processB is calling read_swap_cache_async() about a swap entry *that is used by processA*, a race like below can happen.
processA | processB -------------------------------------+------------------------------------- (free_swap_and_cache()) | (read_swap_cache_async()) | swap_duplicate() | __set_page_locked() | add_to_swap_cache() swap_entry_free() == 0 | find_get_page() -> found | try_lock_page() -> fail & return | | lru_cache_add_anon() | doesn't link this page to memcg's | LRU, because of !PageCgroupUsed.
This type of leak can be avoided by setting /proc/sys/vm/page-cluster to 0.
== Type-2 == Assume processA is exiting and pte points to a page(!PageSwapCache). And processB is trying reclaim the page.
processA | processB -------------------------------------+------------------------------------- (page_remove_rmap()) | (shrink_page_list()) mem_cgroup_uncharge_page() | ->uncharged because it's not | PageSwapCache yet. | So, both mem/memsw.usage | are decremented. | | add_to_swap() -> added to swap cache.
If this page goes thorough without being freed for some reason, this page doesn't goes back to memcg's LRU because of !PageCgroupUsed. ==
This patch is a trial for fixing above problems by fixing memcg's swap account logic. But this requires some amount of changes in swap.
Comaparing with my previous post (22/May) (http://marc.info/?l=linux-mm&m=124297915418698&w=2), I think this one is much easier to read...
[1/5] change interface of swap_duplicate()/swap_free() Adds an function swapcache_prepare() and swapcache_free().
[2/5] add SWAP_HAS_CACHE flag to swap_map Add SWAP_HAS_CACHE flag to swap_map array for knowing an information that "there is an only swap cache and swap has no reference" without calling find_get_page().
[3/5] Count the number of swap-cache-only swaps After repeating swap-in/out, there are tons of cache-only swaps. (via a mapped swapcache under vm_swap_full()==false) This patch counts the number of entry and show it in debug information. (for example, sysrq-m)
[4/5] fix memcg's swap accounting. change the memcg's swap accounting logic to see # of references to swap.
[5/5] experimental garbage collection for cache-only swaps. reclaim swap enty which is not used.
patch [4/5] is for type-1 patch [5/5] is for type-2 and sanity of swaps control...
Thank you for all helps. Any comments are welcome.
Thanks, -Kame
| |