Commit 628f42355389cfb596ca3a5a5f64fb9054a2a06a

Authored by KAMEZAWA Hiroyuki
Committed by Linus Torvalds
1 parent 12b9804419

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
... ... @@ -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)