aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2009-06-17 19:27:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:03:48 -0400
commit22a668d7c3ef833e7d67e9cef587ecc78069d532 (patch)
treeda9f2e7ea7224c347dfe33ea9d4dddd944c861ac
parent8a9478ca7f4bcb8945cec7f95d52dae2d5e50cbd (diff)
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>
-rw-r--r--Documentation/cgroups/memory.txt17
-rw-r--r--mm/memcontrol.c19
2 files changed, 30 insertions, 6 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index 1a608877b14e..af48135bd9b8 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -152,14 +152,19 @@ When swap is accounted, following files are added.
152 152
153usage of mem+swap is limited by memsw.limit_in_bytes. 153usage of mem+swap is limited by memsw.limit_in_bytes.
154 154
155Note: why 'mem+swap' rather than swap. 155* why 'mem+swap' rather than swap.
156The global LRU(kswapd) can swap out arbitrary pages. Swap-out means 156The global LRU(kswapd) can swap out arbitrary pages. Swap-out means
157to move account from memory to swap...there is no change in usage of 157to move account from memory to swap...there is no change in usage of
158mem+swap. 158mem+swap. In other words, when we want to limit the usage of swap without
159 159affecting global LRU, mem+swap limit is better than just limiting swap from
160In other words, when we want to limit the usage of swap without affecting 160OS point of view.
161global LRU, mem+swap limit is better than just limiting swap from OS point 161
162of view. 162* What happens when a cgroup hits memory.memsw.limit_in_bytes
163When a cgroup his memory.memsw.limit_in_bytes, it's useless to do swap-out
164in this cgroup. Then, swap-out will not be done by cgroup routine and file
165caches are dropped. But as mentioned above, global LRU can do swapout memory
166from it for sanity of the system's memory management state. You can't forbid
167it by cgroup.
163 168
1642.5 Reclaim 1692.5 Reclaim
165 170
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a83e0395444b..6ceb6f2dbac2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -177,6 +177,9 @@ struct mem_cgroup {
177 177
178 unsigned int swappiness; 178 unsigned int swappiness;
179 179
180 /* set when res.limit == memsw.limit */
181 bool memsw_is_minimum;
182
180 /* 183 /*
181 * statistics. This must be placed at the end of memcg. 184 * statistics. This must be placed at the end of memcg.
182 */ 185 */
@@ -847,6 +850,10 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem,
847 int ret, total = 0; 850 int ret, total = 0;
848 int loop = 0; 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 while (loop < 2) { 857 while (loop < 2) {
851 victim = mem_cgroup_select_victim(root_mem); 858 victim = mem_cgroup_select_victim(root_mem);
852 if (victim == root_mem) 859 if (victim == root_mem)
@@ -1752,6 +1759,12 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg,
1752 break; 1759 break;
1753 } 1760 }
1754 ret = res_counter_set_limit(&memcg->res, val); 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 mutex_unlock(&set_limit_mutex); 1768 mutex_unlock(&set_limit_mutex);
1756 1769
1757 if (!ret) 1770 if (!ret)
@@ -1799,6 +1812,12 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg,
1799 break; 1812 break;
1800 } 1813 }
1801 ret = res_counter_set_limit(&memcg->memsw, val); 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 mutex_unlock(&set_limit_mutex); 1821 mutex_unlock(&set_limit_mutex);
1803 1822
1804 if (!ret) 1823 if (!ret)