memcgroup: add the max_usage member on the res_counter
authorPavel Emelyanov <xemul@openvz.org>
Tue, 29 Apr 2008 08:00:17 +0000 (01:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Apr 2008 15:06:10 +0000 (08:06 -0700)
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: Pavel Emelyanov <xemul@openvz.org>
Acked-by: Balbir Singh <balbir@linux.vnet.ibm.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
include/linux/res_counter.h
kernel/res_counter.c
mm/memcontrol.c

index 8cb1ecd420a9db3e8d2f0f142f0952a98d196ec8..df8085acba16017f6e1a5da5852d21b0f936cccc 100644 (file)
@@ -24,6 +24,10 @@ struct res_counter {
         * the current resource consumption level
         */
        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
         */
@@ -67,6 +71,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member,
 
 enum {
        RES_USAGE,
+       RES_MAX_USAGE,
        RES_LIMIT,
        RES_FAILCNT,
 };
@@ -127,4 +132,13 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)
        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
index 70587657dda3e6d2751ddc345084c4503a7872f0..d3c61b4ebef238c110ae3994e0d0fdc078fabfc8 100644 (file)
@@ -28,6 +28,8 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
        }
 
        counter->usage += val;
+       if (counter->usage > counter->max_usage)
+               counter->max_usage = counter->usage;
        return 0;
 }
 
@@ -66,6 +68,8 @@ res_counter_member(struct res_counter *counter, int member)
        switch (member) {
        case RES_USAGE:
                return &counter->usage;
+       case RES_MAX_USAGE:
+               return &counter->max_usage;
        case RES_LIMIT:
                return &counter->limit;
        case RES_FAILCNT:
index 49d80814798ba947a0293f04b840238300c68b63..350a14da6525d07730e74020ed966d3dbac98f79 100644 (file)
@@ -855,6 +855,17 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
                                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,
                                struct cftype *cft, struct file *file,
                                const char __user *userbuf,
@@ -909,6 +920,12 @@ static struct cftype mem_cgroup_files[] = {
                .private = RES_USAGE,
                .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",
                .private = RES_LIMIT,