aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/controllers/memory.txt3
-rw-r--r--mm/memcontrol.c48
2 files changed, 45 insertions, 6 deletions
diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt
index 866b9cd9a959..9b53d5827361 100644
--- a/Documentation/controllers/memory.txt
+++ b/Documentation/controllers/memory.txt
@@ -242,8 +242,7 @@ rmdir() if there are no tasks.
2421. Add support for accounting huge pages (as a separate controller) 2421. Add support for accounting huge pages (as a separate controller)
2432. Make per-cgroup scanner reclaim not-shared pages first 2432. Make per-cgroup scanner reclaim not-shared pages first
2443. Teach controller to account for shared-pages 2443. Teach controller to account for shared-pages
2454. Start reclamation when the limit is lowered 2454. Start reclamation in the background when the limit is
2465. Start reclamation in the background when the limit is
247 not yet hit but the usage is getting closer 246 not yet hit but the usage is getting closer
248 247
249Summary 248Summary
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 0c035647d36a..fba566c51322 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -812,6 +812,30 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask)
812 return 0; 812 return 0;
813} 813}
814 814
815int 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 * This routine traverse page_cgroup in given list and drop them all. 840 * This routine traverse page_cgroup in given list and drop them all.
817 * *And* this routine doesn't reclaim page itself, just removes page_cgroup. 841 * *And* this routine doesn't reclaim page itself, just removes page_cgroup.
@@ -896,13 +920,29 @@ static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft)
896 return res_counter_read_u64(&mem_cgroup_from_cont(cont)->res, 920 return res_counter_read_u64(&mem_cgroup_from_cont(cont)->res,
897 cft->private); 921 cft->private);
898} 922}
899 923/*
924 * The user of this function is...
925 * RES_LIMIT.
926 */
900static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, 927static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
901 const char *buffer) 928 const char *buffer)
902{ 929{
903 return res_counter_write(&mem_cgroup_from_cont(cont)->res, 930 struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
904 cft->private, buffer, 931 unsigned long long val;
905 res_counter_memparse_write_strategy); 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
908static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) 948static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)