aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/res_counter.h14
-rw-r--r--kernel/res_counter.c4
-rw-r--r--mm/memcontrol.c17
3 files changed, 35 insertions, 0 deletions
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 8cb1ecd420a9..df8085acba16 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -25,6 +25,10 @@ struct res_counter {
25 */ 25 */
26 unsigned long long usage; 26 unsigned long long usage;
27 /* 27 /*
28 * the maximal value of the usage from the counter creation
29 */
30 unsigned long long max_usage;
31 /*
28 * the limit that usage cannot exceed 32 * the limit that usage cannot exceed
29 */ 33 */
30 unsigned long long limit; 34 unsigned long long limit;
@@ -67,6 +71,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member,
67 71
68enum { 72enum {
69 RES_USAGE, 73 RES_USAGE,
74 RES_MAX_USAGE,
70 RES_LIMIT, 75 RES_LIMIT,
71 RES_FAILCNT, 76 RES_FAILCNT,
72}; 77};
@@ -127,4 +132,13 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)
127 return ret; 132 return ret;
128} 133}
129 134
135static inline void res_counter_reset_max(struct res_counter *cnt)
136{
137 unsigned long flags;
138
139 spin_lock_irqsave(&cnt->lock, flags);
140 cnt->max_usage = cnt->usage;
141 spin_unlock_irqrestore(&cnt->lock, flags);
142}
143
130#endif 144#endif
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 70587657dda3..d3c61b4ebef2 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -28,6 +28,8 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
28 } 28 }
29 29
30 counter->usage += val; 30 counter->usage += val;
31 if (counter->usage > counter->max_usage)
32 counter->max_usage = counter->usage;
31 return 0; 33 return 0;
32} 34}
33 35
@@ -66,6 +68,8 @@ res_counter_member(struct res_counter *counter, int member)
66 switch (member) { 68 switch (member) {
67 case RES_USAGE: 69 case RES_USAGE:
68 return &counter->usage; 70 return &counter->usage;
71 case RES_MAX_USAGE:
72 return &counter->max_usage;
69 case RES_LIMIT: 73 case RES_LIMIT:
70 return &counter->limit; 74 return &counter->limit;
71 case RES_FAILCNT: 75 case RES_FAILCNT:
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 49d80814798b..350a14da6525 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -855,6 +855,17 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
855 mem_cgroup_write_strategy); 855 mem_cgroup_write_strategy);
856} 856}
857 857
858static ssize_t mem_cgroup_max_reset(struct cgroup *cont, struct cftype *cft,
859 struct file *file, const char __user *userbuf,
860 size_t nbytes, loff_t *ppos)
861{
862 struct mem_cgroup *mem;
863
864 mem = mem_cgroup_from_cont(cont);
865 res_counter_reset_max(&mem->res);
866 return nbytes;
867}
868
858static ssize_t mem_force_empty_write(struct cgroup *cont, 869static ssize_t mem_force_empty_write(struct cgroup *cont,
859 struct cftype *cft, struct file *file, 870 struct cftype *cft, struct file *file,
860 const char __user *userbuf, 871 const char __user *userbuf,
@@ -910,6 +921,12 @@ static struct cftype mem_cgroup_files[] = {
910 .read_u64 = mem_cgroup_read, 921 .read_u64 = mem_cgroup_read,
911 }, 922 },
912 { 923 {
924 .name = "max_usage_in_bytes",
925 .private = RES_MAX_USAGE,
926 .write = mem_cgroup_max_reset,
927 .read_u64 = mem_cgroup_read,
928 },
929 {
913 .name = "limit_in_bytes", 930 .name = "limit_in_bytes",
914 .private = RES_LIMIT, 931 .private = RES_LIMIT,
915 .write = mem_cgroup_write, 932 .write = mem_cgroup_write,