]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/memcontrol.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[karo-tx-linux.git] / mm / memcontrol.c
index 425aa0caa712d9fb3a30051e246fe07eb4562800..3df3c04d73ab08e3bbb663f25b2e195b396d2149 100644 (file)
@@ -631,7 +631,7 @@ static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg,
        val = __this_cpu_read(memcg->stat->nr_page_events);
        next = __this_cpu_read(memcg->stat->targets[target]);
        /* from time_after() in jiffies.h */
-       if ((long)next - (long)val < 0) {
+       if ((long)(next - val) < 0) {
                switch (target) {
                case MEM_CGROUP_TARGET_THRESH:
                        next = val + THRESHOLDS_EVENTS_TARGET;
@@ -5317,38 +5317,52 @@ struct cgroup_subsys memory_cgrp_subsys = {
 
 /**
  * mem_cgroup_low - check if memory consumption is below the normal range
- * @root: the highest ancestor to consider
+ * @root: the top ancestor of the sub-tree being checked
  * @memcg: the memory cgroup to check
  *
  * Returns %true if memory consumption of @memcg, and that of all
- * configurable ancestors up to @root, is below the normal range.
+ * ancestors up to (but not including) @root, is below the normal range.
+ *
+ * @root is exclusive; it is never low when looked at directly and isn't
+ * checked when traversing the hierarchy.
+ *
+ * Excluding @root enables using memory.low to prioritize memory usage
+ * between cgroups within a subtree of the hierarchy that is limited by
+ * memory.high or memory.max.
+ *
+ * For example, given cgroup A with children B and C:
+ *
+ *    A
+ *   / \
+ *  B   C
+ *
+ * and
+ *
+ *  1. A/memory.current > A/memory.high
+ *  2. A/B/memory.current < A/B/memory.low
+ *  3. A/C/memory.current >= A/C/memory.low
+ *
+ * As 'A' is high, i.e. triggers reclaim from 'A', and 'B' is low, we
+ * should reclaim from 'C' until 'A' is no longer high or until we can
+ * no longer reclaim from 'C'.  If 'A', i.e. @root, isn't excluded by
+ * mem_cgroup_low when reclaming from 'A', then 'B' won't be considered
+ * low and we will reclaim indiscriminately from both 'B' and 'C'.
  */
 bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg)
 {
        if (mem_cgroup_disabled())
                return false;
 
-       /*
-        * The toplevel group doesn't have a configurable range, so
-        * it's never low when looked at directly, and it is not
-        * considered an ancestor when assessing the hierarchy.
-        */
-
-       if (memcg == root_mem_cgroup)
-               return false;
-
-       if (page_counter_read(&memcg->memory) >= memcg->low)
+       if (!root)
+               root = root_mem_cgroup;
+       if (memcg == root)
                return false;
 
-       while (memcg != root) {
-               memcg = parent_mem_cgroup(memcg);
-
-               if (memcg == root_mem_cgroup)
-                       break;
-
+       for (; memcg != root; memcg = parent_mem_cgroup(memcg)) {
                if (page_counter_read(&memcg->memory) >= memcg->low)
                        return false;
        }
+
        return true;
 }