memcg: move charges to root cgroup if use_hierarchy=0
[pandora-kernel.git] / mm / memblock.c
index a44eab3..952123e 100644 (file)
@@ -37,6 +37,8 @@ struct memblock memblock __initdata_memblock = {
 
 int memblock_debug __initdata_memblock;
 static int memblock_can_resize __initdata_memblock;
+static int memblock_memory_in_slab __initdata_memblock = 0;
+static int memblock_reserved_in_slab __initdata_memblock = 0;
 
 /* inline so we don't get a warning when pr_debug is compiled out */
 static inline const char *memblock_type_name(struct memblock_type *type)
@@ -187,6 +189,7 @@ static int __init_memblock memblock_double_array(struct memblock_type *type)
        struct memblock_region *new_array, *old_array;
        phys_addr_t old_size, new_size, addr;
        int use_slab = slab_is_available();
+       int *in_slab;
 
        /* We don't allow resizing until we know about the reserved regions
         * of memory that aren't suitable for allocation
@@ -198,6 +201,12 @@ static int __init_memblock memblock_double_array(struct memblock_type *type)
        old_size = type->max * sizeof(struct memblock_region);
        new_size = old_size << 1;
 
+       /* Retrieve the slab flag */
+       if (type == &memblock.memory)
+               in_slab = &memblock_memory_in_slab;
+       else
+               in_slab = &memblock_reserved_in_slab;
+
        /* Try to find some space for it.
         *
         * WARNING: We assume that either slab_is_available() and we use it or
@@ -212,14 +221,15 @@ static int __init_memblock memblock_double_array(struct memblock_type *type)
        if (use_slab) {
                new_array = kmalloc(new_size, GFP_KERNEL);
                addr = new_array ? __pa(new_array) : 0;
-       } else
+       } else {
                addr = memblock_find_in_range(0, MEMBLOCK_ALLOC_ACCESSIBLE, new_size, sizeof(phys_addr_t));
+               new_array = addr ? __va(addr) : 0;
+       }
        if (!addr) {
                pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
                       memblock_type_name(type), type->max, type->max * 2);
                return -1;
        }
-       new_array = __va(addr);
 
        memblock_dbg("memblock: %s array is doubled to %ld at [%#010llx-%#010llx]",
                 memblock_type_name(type), type->max * 2, (u64)addr, (u64)addr + new_size - 1);
@@ -234,22 +244,24 @@ static int __init_memblock memblock_double_array(struct memblock_type *type)
        type->regions = new_array;
        type->max <<= 1;
 
-       /* If we use SLAB that's it, we are done */
-       if (use_slab)
-               return 0;
-
-       /* Add the new reserved region now. Should not fail ! */
-       BUG_ON(memblock_reserve(addr, new_size));
-
-       /* If the array wasn't our static init one, then free it. We only do
-        * that before SLAB is available as later on, we don't know whether
-        * to use kfree or free_bootmem_pages(). Shouldn't be a big deal
-        * anyways
+       /* Free old array. We needn't free it if the array is the
+        * static one
         */
-       if (old_array != memblock_memory_init_regions &&
-           old_array != memblock_reserved_init_regions)
+       if (*in_slab)
+               kfree(old_array);
+       else if (old_array != memblock_memory_init_regions &&
+                old_array != memblock_reserved_init_regions)
                memblock_free(__pa(old_array), old_size);
 
+       /* Reserve the new array if that comes from the memblock.
+        * Otherwise, we needn't do it
+        */
+       if (!use_slab)
+               BUG_ON(memblock_reserve(addr, new_size));
+
+       /* Update slab flag */
+       *in_slab = use_slab;
+
        return 0;
 }