mm, treewide: redefine MAX_ORDER sanely
[linux-2.6-block.git] / mm / memblock.c
index d036c7861310cbfb0efcc36ee36279877978d171..7911224b1ed392e23d17bfd3db738b16a4d66684 100644 (file)
@@ -500,15 +500,19 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
 /**
  * memblock_merge_regions - merge neighboring compatible regions
  * @type: memblock type to scan
- *
- * Scan @type and merge neighboring compatible regions.
+ * @start_rgn: start scanning from (@start_rgn - 1)
+ * @end_rgn: end scanning at (@end_rgn - 1)
+ * Scan @type and merge neighboring compatible regions in [@start_rgn - 1, @end_rgn)
  */
-static void __init_memblock memblock_merge_regions(struct memblock_type *type)
+static void __init_memblock memblock_merge_regions(struct memblock_type *type,
+                                                  unsigned long start_rgn,
+                                                  unsigned long end_rgn)
 {
        int i = 0;
-
-       /* cnt never goes below 1 */
-       while (i < type->cnt - 1) {
+       if (start_rgn)
+               i = start_rgn - 1;
+       end_rgn = min(end_rgn, type->cnt - 1);
+       while (i < end_rgn) {
                struct memblock_region *this = &type->regions[i];
                struct memblock_region *next = &type->regions[i + 1];
 
@@ -525,6 +529,7 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
                /* move forward from next + 1, index of which is i + 2 */
                memmove(next, next + 1, (type->cnt - (i + 2)) * sizeof(*next));
                type->cnt--;
+               end_rgn--;
        }
 }
 
@@ -581,7 +586,7 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
        bool insert = false;
        phys_addr_t obase = base;
        phys_addr_t end = base + memblock_cap_size(base, &size);
-       int idx, nr_new;
+       int idx, nr_new, start_rgn = -1, end_rgn;
        struct memblock_region *rgn;
 
        if (!size)
@@ -601,11 +606,11 @@ static int __init_memblock memblock_add_range(struct memblock_type *type,
        /*
         * The worst case is when new range overlaps all existing regions,
         * then we'll need type->cnt + 1 empty regions in @type. So if
-        * type->cnt * 2 + 1 is less than type->max, we know
+        * type->cnt * 2 + 1 is less than or equal to type->max, we know
         * that there is enough empty regions in @type, and we can insert
         * regions directly.
         */
-       if (type->cnt * 2 + 1 < type->max)
+       if (type->cnt * 2 + 1 <= type->max)
                insert = true;
 
 repeat:
@@ -635,10 +640,14 @@ repeat:
 #endif
                        WARN_ON(flags != rgn->flags);
                        nr_new++;
-                       if (insert)
+                       if (insert) {
+                               if (start_rgn == -1)
+                                       start_rgn = idx;
+                               end_rgn = idx + 1;
                                memblock_insert_region(type, idx++, base,
                                                       rbase - base, nid,
                                                       flags);
+                       }
                }
                /* area below @rend is dealt with, forget about it */
                base = min(rend, end);
@@ -647,9 +656,13 @@ repeat:
        /* insert the remaining portion */
        if (base < end) {
                nr_new++;
-               if (insert)
+               if (insert) {
+                       if (start_rgn == -1)
+                               start_rgn = idx;
+                       end_rgn = idx + 1;
                        memblock_insert_region(type, idx, base, end - base,
                                               nid, flags);
+               }
        }
 
        if (!nr_new)
@@ -666,7 +679,7 @@ repeat:
                insert = true;
                goto repeat;
        } else {
-               memblock_merge_regions(type);
+               memblock_merge_regions(type, start_rgn, end_rgn);
                return 0;
        }
 }
@@ -902,7 +915,7 @@ static int __init_memblock memblock_setclr_flag(phys_addr_t base,
                        r->flags &= ~flag;
        }
 
-       memblock_merge_regions(type);
+       memblock_merge_regions(type, start_rgn, end_rgn);
        return 0;
 }
 
@@ -1275,7 +1288,7 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
        for (i = start_rgn; i < end_rgn; i++)
                memblock_set_region_node(&type->regions[i], nid);
 
-       memblock_merge_regions(type);
+       memblock_merge_regions(type, start_rgn, end_rgn);
 #endif
        return 0;
 }
@@ -2030,7 +2043,7 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end)
        int order;
 
        while (start < end) {
-               order = min(MAX_ORDER - 1UL, __ffs(start));
+               order = min_t(int, MAX_ORDER, __ffs(start));
 
                while (start + (1UL << order) > end)
                        order--;