]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/memblock.c
Merge tag 'trace-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[karo-tx-linux.git] / mm / memblock.c
index 7608bc305936177f03dcf92eda29c1eb818cdc2f..b64b47803e529a87d87f3e3f022e97f17ff606be 100644 (file)
@@ -35,15 +35,18 @@ struct memblock memblock __initdata_memblock = {
        .memory.regions         = memblock_memory_init_regions,
        .memory.cnt             = 1,    /* empty dummy entry */
        .memory.max             = INIT_MEMBLOCK_REGIONS,
+       .memory.name            = "memory",
 
        .reserved.regions       = memblock_reserved_init_regions,
        .reserved.cnt           = 1,    /* empty dummy entry */
        .reserved.max           = INIT_MEMBLOCK_REGIONS,
+       .reserved.name          = "reserved",
 
 #ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
        .physmem.regions        = memblock_physmem_init_regions,
        .physmem.cnt            = 1,    /* empty dummy entry */
        .physmem.max            = INIT_PHYSMEM_REGIONS,
+       .physmem.name           = "physmem",
 #endif
 
        .bottom_up              = false,
@@ -64,18 +67,6 @@ ulong __init_memblock choose_memblock_flags(void)
        return system_has_some_mirror ? MEMBLOCK_MIRROR : MEMBLOCK_NONE;
 }
 
-/* inline so we don't get a warning when pr_debug is compiled out */
-static __init_memblock const char *
-memblock_type_name(struct memblock_type *type)
-{
-       if (type == &memblock.memory)
-               return "memory";
-       else if (type == &memblock.reserved)
-               return "reserved";
-       else
-               return "unknown";
-}
-
 /* adjust *@size so that (@base + *@size) doesn't overflow, return new size */
 static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size)
 {
@@ -402,12 +393,12 @@ static int __init_memblock memblock_double_array(struct memblock_type *type,
        }
        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);
+                      type->name, type->max, type->max * 2);
                return -1;
        }
 
        memblock_dbg("memblock: %s is doubled to %ld at [%#010llx-%#010llx]",
-                       memblock_type_name(type), type->max * 2, (u64)addr,
+                       type->name, type->max * 2, (u64)addr,
                        (u64)addr + new_size - 1);
 
        /*
@@ -611,10 +602,10 @@ int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size,
 
 int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
 {
-       memblock_dbg("memblock_add: [%#016llx-%#016llx] flags %#02lx %pF\n",
-                    (unsigned long long)base,
-                    (unsigned long long)base + size - 1,
-                    0UL, (void *)_RET_IP_);
+       phys_addr_t end = base + size - 1;
+
+       memblock_dbg("memblock_add: [%pa-%pa] %pF\n",
+                    &base, &end, (void *)_RET_IP_);
 
        return memblock_add_range(&memblock.memory, base, size, MAX_NUMNODES, 0);
 }
@@ -718,10 +709,10 @@ int __init_memblock memblock_remove(phys_addr_t base, phys_addr_t size)
 
 int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
 {
-       memblock_dbg("   memblock_free: [%#016llx-%#016llx] %pF\n",
-                    (unsigned long long)base,
-                    (unsigned long long)base + size - 1,
-                    (void *)_RET_IP_);
+       phys_addr_t end = base + size - 1;
+
+       memblock_dbg("   memblock_free: [%pa-%pa] %pF\n",
+                    &base, &end, (void *)_RET_IP_);
 
        kmemleak_free_part_phys(base, size);
        return memblock_remove_range(&memblock.reserved, base, size);
@@ -729,10 +720,10 @@ int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
 
 int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
 {
-       memblock_dbg("memblock_reserve: [%#016llx-%#016llx] flags %#02lx %pF\n",
-                    (unsigned long long)base,
-                    (unsigned long long)base + size - 1,
-                    0UL, (void *)_RET_IP_);
+       phys_addr_t end = base + size - 1;
+
+       memblock_dbg("memblock_reserve: [%pa-%pa] %pF\n",
+                    &base, &end, (void *)_RET_IP_);
 
        return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0);
 }
@@ -1105,6 +1096,31 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
                *out_nid = r->nid;
 }
 
+unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn,
+                                                     unsigned long max_pfn)
+{
+       struct memblock_type *type = &memblock.memory;
+       unsigned int right = type->cnt;
+       unsigned int mid, left = 0;
+       phys_addr_t addr = PFN_PHYS(pfn + 1);
+
+       do {
+               mid = (right + left) / 2;
+
+               if (addr < type->regions[mid].base)
+                       right = mid;
+               else if (addr >= (type->regions[mid].base +
+                                 type->regions[mid].size))
+                       left = mid + 1;
+               else {
+                       /* addr is within the region, so pfn + 1 is valid */
+                       return min(pfn + 1, max_pfn);
+               }
+       } while (left < right);
+
+       return min(PHYS_PFN(type->regions[right].base), max_pfn);
+}
+
 /**
  * memblock_set_node - set node ID on memblock regions
  * @base: base of area to set node ID for
@@ -1202,8 +1218,8 @@ phys_addr_t __init memblock_alloc_base(phys_addr_t size, phys_addr_t align, phys
        alloc = __memblock_alloc_base(size, align, max_addr);
 
        if (alloc == 0)
-               panic("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n",
-                     (unsigned long long) size, (unsigned long long) max_addr);
+               panic("ERROR: Failed to allocate %pa bytes below %pa.\n",
+                     &size, &max_addr);
 
        return alloc;
 }
@@ -1274,18 +1290,17 @@ static void * __init memblock_virt_alloc_internal(
 
        if (max_addr > memblock.current_limit)
                max_addr = memblock.current_limit;
-
 again:
        alloc = memblock_find_in_range_node(size, align, min_addr, max_addr,
                                            nid, flags);
-       if (alloc)
+       if (alloc && !memblock_reserve(alloc, size))
                goto done;
 
        if (nid != NUMA_NO_NODE) {
                alloc = memblock_find_in_range_node(size, align, min_addr,
                                                    max_addr, NUMA_NO_NODE,
                                                    flags);
-               if (alloc)
+               if (alloc && !memblock_reserve(alloc, size))
                        goto done;
        }
 
@@ -1303,7 +1318,6 @@ again:
 
        return NULL;
 done:
-       memblock_reserve(alloc, size);
        ptr = phys_to_virt(alloc);
        memset(ptr, 0, size);
 
@@ -1615,8 +1629,7 @@ int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size
 
        if (idx == -1)
                return 0;
-       return memblock.memory.regions[idx].base <= base &&
-               (memblock.memory.regions[idx].base +
+       return (memblock.memory.regions[idx].base +
                 memblock.memory.regions[idx].size) >= end;
 }
 
@@ -1671,40 +1684,44 @@ phys_addr_t __init_memblock memblock_get_current_limit(void)
        return memblock.current_limit;
 }
 
-static void __init_memblock memblock_dump(struct memblock_type *type, char *name)
+static void __init_memblock memblock_dump(struct memblock_type *type)
 {
-       unsigned long long base, size;
+       phys_addr_t base, end, size;
        unsigned long flags;
        int idx;
        struct memblock_region *rgn;
 
-       pr_info(" %s.cnt  = 0x%lx\n", name, type->cnt);
+       pr_info(" %s.cnt  = 0x%lx\n", type->name, type->cnt);
 
        for_each_memblock_type(type, rgn) {
                char nid_buf[32] = "";
 
                base = rgn->base;
                size = rgn->size;
+               end = base + size - 1;
                flags = rgn->flags;
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
                if (memblock_get_region_node(rgn) != MAX_NUMNODES)
                        snprintf(nid_buf, sizeof(nid_buf), " on node %d",
                                 memblock_get_region_node(rgn));
 #endif
-               pr_info(" %s[%#x]\t[%#016llx-%#016llx], %#llx bytes%s flags: %#lx\n",
-                       name, idx, base, base + size - 1, size, nid_buf, flags);
+               pr_info(" %s[%#x]\t[%pa-%pa], %pa bytes%s flags: %#lx\n",
+                       type->name, idx, &base, &end, &size, nid_buf, flags);
        }
 }
 
 void __init_memblock __memblock_dump_all(void)
 {
        pr_info("MEMBLOCK configuration:\n");
-       pr_info(" memory size = %#llx reserved size = %#llx\n",
-               (unsigned long long)memblock.memory.total_size,
-               (unsigned long long)memblock.reserved.total_size);
+       pr_info(" memory size = %pa reserved size = %pa\n",
+               &memblock.memory.total_size,
+               &memblock.reserved.total_size);
 
-       memblock_dump(&memblock.memory, "memory");
-       memblock_dump(&memblock.reserved, "reserved");
+       memblock_dump(&memblock.memory);
+       memblock_dump(&memblock.reserved);
+#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
+       memblock_dump(&memblock.physmem);
+#endif
 }
 
 void __init memblock_allow_resize(void)
@@ -1727,19 +1744,14 @@ static int memblock_debug_show(struct seq_file *m, void *private)
        struct memblock_type *type = m->private;
        struct memblock_region *reg;
        int i;
+       phys_addr_t end;
 
        for (i = 0; i < type->cnt; i++) {
                reg = &type->regions[i];
-               seq_printf(m, "%4d: ", i);
-               if (sizeof(phys_addr_t) == 4)
-                       seq_printf(m, "0x%08lx..0x%08lx\n",
-                                  (unsigned long)reg->base,
-                                  (unsigned long)(reg->base + reg->size - 1));
-               else
-                       seq_printf(m, "0x%016llx..0x%016llx\n",
-                                  (unsigned long long)reg->base,
-                                  (unsigned long long)(reg->base + reg->size - 1));
+               end = reg->base + reg->size - 1;
 
+               seq_printf(m, "%4d: ", i);
+               seq_printf(m, "%pa..%pa\n", &reg->base, &end);
        }
        return 0;
 }