Commit c84872e1 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Linus Torvalds

memcgroup: add the max_usage member on the res_counter

This field is the maximal value of the usage one since the counter creation
(or since the latest reset).

To reset this to the usage value simply write anything to the appropriate
cgroup file.
Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Acked-by: default avatarBalbir Singh <balbir@linux.vnet.ibm.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent cf475ad2
...@@ -24,6 +24,10 @@ struct res_counter { ...@@ -24,6 +24,10 @@ struct res_counter {
* the current resource consumption level * the current resource consumption level
*/ */
unsigned long long usage; unsigned long long usage;
/*
* the maximal value of the usage from the counter creation
*/
unsigned long long max_usage;
/* /*
* the limit that usage cannot exceed * the limit that usage cannot exceed
*/ */
...@@ -67,6 +71,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member, ...@@ -67,6 +71,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member,
enum { enum {
RES_USAGE, RES_USAGE,
RES_MAX_USAGE,
RES_LIMIT, RES_LIMIT,
RES_FAILCNT, RES_FAILCNT,
}; };
...@@ -127,4 +132,13 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt) ...@@ -127,4 +132,13 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)
return ret; return ret;
} }
static inline void res_counter_reset_max(struct res_counter *cnt)
{
unsigned long flags;
spin_lock_irqsave(&cnt->lock, flags);
cnt->max_usage = cnt->usage;
spin_unlock_irqrestore(&cnt->lock, flags);
}
#endif #endif
...@@ -28,6 +28,8 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val) ...@@ -28,6 +28,8 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
} }
counter->usage += val; counter->usage += val;
if (counter->usage > counter->max_usage)
counter->max_usage = counter->usage;
return 0; return 0;
} }
...@@ -66,6 +68,8 @@ res_counter_member(struct res_counter *counter, int member) ...@@ -66,6 +68,8 @@ res_counter_member(struct res_counter *counter, int member)
switch (member) { switch (member) {
case RES_USAGE: case RES_USAGE:
return &counter->usage; return &counter->usage;
case RES_MAX_USAGE:
return &counter->max_usage;
case RES_LIMIT: case RES_LIMIT:
return &counter->limit; return &counter->limit;
case RES_FAILCNT: case RES_FAILCNT:
......
...@@ -855,6 +855,17 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft, ...@@ -855,6 +855,17 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
mem_cgroup_write_strategy); mem_cgroup_write_strategy);
} }
static ssize_t mem_cgroup_max_reset(struct cgroup *cont, struct cftype *cft,
struct file *file, const char __user *userbuf,
size_t nbytes, loff_t *ppos)
{
struct mem_cgroup *mem;
mem = mem_cgroup_from_cont(cont);
res_counter_reset_max(&mem->res);
return nbytes;
}
static ssize_t mem_force_empty_write(struct cgroup *cont, static ssize_t mem_force_empty_write(struct cgroup *cont,
struct cftype *cft, struct file *file, struct cftype *cft, struct file *file,
const char __user *userbuf, const char __user *userbuf,
...@@ -909,6 +920,12 @@ static struct cftype mem_cgroup_files[] = { ...@@ -909,6 +920,12 @@ static struct cftype mem_cgroup_files[] = {
.private = RES_USAGE, .private = RES_USAGE,
.read_u64 = mem_cgroup_read, .read_u64 = mem_cgroup_read,
}, },
{
.name = "max_usage_in_bytes",
.private = RES_MAX_USAGE,
.write = mem_cgroup_max_reset,
.read_u64 = mem_cgroup_read,
},
{ {
.name = "limit_in_bytes", .name = "limit_in_bytes",
.private = RES_LIMIT, .private = RES_LIMIT,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment