diff options
-rw-r--r-- | include/linux/res_counter.h | 14 | ||||
-rw-r--r-- | kernel/res_counter.c | 4 | ||||
-rw-r--r-- | mm/memcontrol.c | 17 |
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 | ||
68 | enum { | 72 | enum { |
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 | ||
135 | static 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 | ||
858 | static 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 | |||
858 | static ssize_t mem_force_empty_write(struct cgroup *cont, | 869 | static 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, |