Commit 22a668d7c3ef833e7d67e9cef587ecc78069d532
Committed by
Linus Torvalds
1 parent
8a9478ca7f
Exists in
master
and in
7 other branches
memcg: fix behavior under memory.limit equals to memsw.limit
A user can set memcg.limit_in_bytes == memcg.memsw.limit_in_bytes when the user just want to limit the total size of applications, in other words, not very interested in memory usage itself. In this case, swap-out will be done only by global-LRU. But, under current implementation, memory.limit_in_bytes is checked at first and try_to_free_page() may do swap-out. But, that swap-out is useless for memsw.limit_in_bytes and the thread may hit limit again. This patch tries to fix the current behavior at memory.limit == memsw.limit case. And documentation is updated to explain the behavior of this special case. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Dhaval Giani <dhaval@linux.vnet.ibm.com> Cc: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 30 additions and 6 deletions Side-by-side Diff
Documentation/cgroups/memory.txt
... | ... | @@ -152,14 +152,19 @@ |
152 | 152 | |
153 | 153 | usage of mem+swap is limited by memsw.limit_in_bytes. |
154 | 154 | |
155 | -Note: why 'mem+swap' rather than swap. | |
155 | +* why 'mem+swap' rather than swap. | |
156 | 156 | The global LRU(kswapd) can swap out arbitrary pages. Swap-out means |
157 | 157 | to move account from memory to swap...there is no change in usage of |
158 | -mem+swap. | |
158 | +mem+swap. In other words, when we want to limit the usage of swap without | |
159 | +affecting global LRU, mem+swap limit is better than just limiting swap from | |
160 | +OS point of view. | |
159 | 161 | |
160 | -In other words, when we want to limit the usage of swap without affecting | |
161 | -global LRU, mem+swap limit is better than just limiting swap from OS point | |
162 | -of view. | |
162 | +* What happens when a cgroup hits memory.memsw.limit_in_bytes | |
163 | +When a cgroup his memory.memsw.limit_in_bytes, it's useless to do swap-out | |
164 | +in this cgroup. Then, swap-out will not be done by cgroup routine and file | |
165 | +caches are dropped. But as mentioned above, global LRU can do swapout memory | |
166 | +from it for sanity of the system's memory management state. You can't forbid | |
167 | +it by cgroup. | |
163 | 168 | |
164 | 169 | 2.5 Reclaim |
165 | 170 |
mm/memcontrol.c
... | ... | @@ -177,6 +177,9 @@ |
177 | 177 | |
178 | 178 | unsigned int swappiness; |
179 | 179 | |
180 | + /* set when res.limit == memsw.limit */ | |
181 | + bool memsw_is_minimum; | |
182 | + | |
180 | 183 | /* |
181 | 184 | * statistics. This must be placed at the end of memcg. |
182 | 185 | */ |
... | ... | @@ -847,6 +850,10 @@ |
847 | 850 | int ret, total = 0; |
848 | 851 | int loop = 0; |
849 | 852 | |
853 | + /* If memsw_is_minimum==1, swap-out is of-no-use. */ | |
854 | + if (root_mem->memsw_is_minimum) | |
855 | + noswap = true; | |
856 | + | |
850 | 857 | while (loop < 2) { |
851 | 858 | victim = mem_cgroup_select_victim(root_mem); |
852 | 859 | if (victim == root_mem) |
... | ... | @@ -1752,6 +1759,12 @@ |
1752 | 1759 | break; |
1753 | 1760 | } |
1754 | 1761 | ret = res_counter_set_limit(&memcg->res, val); |
1762 | + if (!ret) { | |
1763 | + if (memswlimit == val) | |
1764 | + memcg->memsw_is_minimum = true; | |
1765 | + else | |
1766 | + memcg->memsw_is_minimum = false; | |
1767 | + } | |
1755 | 1768 | mutex_unlock(&set_limit_mutex); |
1756 | 1769 | |
1757 | 1770 | if (!ret) |
... | ... | @@ -1799,6 +1812,12 @@ |
1799 | 1812 | break; |
1800 | 1813 | } |
1801 | 1814 | ret = res_counter_set_limit(&memcg->memsw, val); |
1815 | + if (!ret) { | |
1816 | + if (memlimit == val) | |
1817 | + memcg->memsw_is_minimum = true; | |
1818 | + else | |
1819 | + memcg->memsw_is_minimum = false; | |
1820 | + } | |
1802 | 1821 | mutex_unlock(&set_limit_mutex); |
1803 | 1822 | |
1804 | 1823 | if (!ret) |