]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cgroups: add res counter common ancestor searching
authorKirill A. Shutemov <kirill@shutemov.name>
Wed, 5 Oct 2011 00:43:47 +0000 (11:43 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 5 Oct 2011 07:56:06 +0000 (18:56 +1100)
Add a new API to find the common ancestor between two resource counters.
This includes the passed resource counter themselves.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Paul Menage <paul@paulmenage.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Aditya Kali <adityakali@google.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Tim Hockin <thockin@hockin.org>
Cc: Tejun Heo <htejun@gmail.com>
Cc: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Andrew Morton <akpm@google.com>
include/linux/res_counter.h
kernel/res_counter.c

index de4ba29cd9f67beaf1f13744c25814219a47a095..558f39b1f86f9fb77a8c8f10e8f6cd501cebe02e 100644 (file)
@@ -147,6 +147,9 @@ static inline void res_counter_uncharge(struct res_counter *counter,
        res_counter_uncharge_until(counter, NULL, val);
 }
 
+struct res_counter *res_counter_common_ancestor(struct res_counter *l,
+                                               struct res_counter *r);
+
 /**
  * res_counter_margin - calculate chargeable space of a counter
  * @cnt: the counter
index 0cc9c7e7131314db7d374fcf47aa75326844fccb..8f4c728ccee09d1c0e67cdc8dd3111bd981e0750 100644 (file)
@@ -91,6 +91,39 @@ void res_counter_uncharge_until(struct res_counter *counter,
        local_irq_restore(flags);
 }
 
+/*
+ * Walk through r1 and r2 parents and try to find the closest common one
+ * between both. If none is found, it returns NULL.
+ */
+struct res_counter *
+res_counter_common_ancestor(struct res_counter *r1, struct res_counter *r2)
+{
+       struct res_counter *iter;
+       int r1_depth = 0, r2_depth = 0;
+
+       for (iter = r1; iter; iter = iter->parent)
+               r1_depth++;
+
+       for (iter = r2; iter; iter = iter->parent)
+               r2_depth++;
+
+       while (r1_depth > r2_depth) {
+               r1 = r1->parent;
+               r1_depth--;
+       }
+
+       while (r2_depth > r1_depth) {
+               r2 = r2->parent;
+               r2_depth--;
+       }
+
+       while (r1 != r2) {
+               r1 = r1->parent;
+               r2 = r2->parent;
+       }
+
+       return r1;
+}
 
 static inline unsigned long long *
 res_counter_member(struct res_counter *counter, int member)