Commit 628f42355389cfb596ca3a5a5f64fb9054a2a06a
Committed by
Linus Torvalds
1 parent
12b9804419
Exists in
master
and in
4 other branches
memcg: limit change shrink usage
Shrinking memory usage at limit change. [akpm@linux-foundation.org: coding-style fixes] Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com> Acked-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Paul Menage <menage@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 45 additions and 6 deletions Side-by-side Diff
Documentation/controllers/memory.txt
... | ... | @@ -242,8 +242,7 @@ |
242 | 242 | 1. Add support for accounting huge pages (as a separate controller) |
243 | 243 | 2. Make per-cgroup scanner reclaim not-shared pages first |
244 | 244 | 3. Teach controller to account for shared-pages |
245 | -4. Start reclamation when the limit is lowered | |
246 | -5. Start reclamation in the background when the limit is | |
245 | +4. Start reclamation in the background when the limit is | |
247 | 246 | not yet hit but the usage is getting closer |
248 | 247 | |
249 | 248 | Summary |
mm/memcontrol.c
... | ... | @@ -812,6 +812,30 @@ |
812 | 812 | return 0; |
813 | 813 | } |
814 | 814 | |
815 | +int mem_cgroup_resize_limit(struct mem_cgroup *memcg, unsigned long long val) | |
816 | +{ | |
817 | + | |
818 | + int retry_count = MEM_CGROUP_RECLAIM_RETRIES; | |
819 | + int progress; | |
820 | + int ret = 0; | |
821 | + | |
822 | + while (res_counter_set_limit(&memcg->res, val)) { | |
823 | + if (signal_pending(current)) { | |
824 | + ret = -EINTR; | |
825 | + break; | |
826 | + } | |
827 | + if (!retry_count) { | |
828 | + ret = -EBUSY; | |
829 | + break; | |
830 | + } | |
831 | + progress = try_to_free_mem_cgroup_pages(memcg, GFP_KERNEL); | |
832 | + if (!progress) | |
833 | + retry_count--; | |
834 | + } | |
835 | + return ret; | |
836 | +} | |
837 | + | |
838 | + | |
815 | 839 | /* |
816 | 840 | * This routine traverse page_cgroup in given list and drop them all. |
817 | 841 | * *And* this routine doesn't reclaim page itself, just removes page_cgroup. |
818 | 842 | |
... | ... | @@ -896,13 +920,29 @@ |
896 | 920 | return res_counter_read_u64(&mem_cgroup_from_cont(cont)->res, |
897 | 921 | cft->private); |
898 | 922 | } |
899 | - | |
923 | +/* | |
924 | + * The user of this function is... | |
925 | + * RES_LIMIT. | |
926 | + */ | |
900 | 927 | static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, |
901 | 928 | const char *buffer) |
902 | 929 | { |
903 | - return res_counter_write(&mem_cgroup_from_cont(cont)->res, | |
904 | - cft->private, buffer, | |
905 | - res_counter_memparse_write_strategy); | |
930 | + struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | |
931 | + unsigned long long val; | |
932 | + int ret; | |
933 | + | |
934 | + switch (cft->private) { | |
935 | + case RES_LIMIT: | |
936 | + /* This function does all necessary parse...reuse it */ | |
937 | + ret = res_counter_memparse_write_strategy(buffer, &val); | |
938 | + if (!ret) | |
939 | + ret = mem_cgroup_resize_limit(memcg, val); | |
940 | + break; | |
941 | + default: | |
942 | + ret = -EINVAL; /* should be BUG() ? */ | |
943 | + break; | |
944 | + } | |
945 | + return ret; | |
906 | 946 | } |
907 | 947 | |
908 | 948 | static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) |