aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memblock.c
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2014-01-21 18:50:19 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 19:19:46 -0500
commit26f09e9b3a0696f6fe20b021901300fba26fb579 (patch)
tree1f595392e4f88f44ea47652f799cc80497e1b9e7 /mm/memblock.c
parentb115423357e0cda6d8f45d0c81df537d7b004020 (diff)
mm/memblock: add memblock memory allocation apis
Introduce memblock memory allocation APIs which allow to support PAE or LPAE extension on 32 bits archs where the physical memory start address can be beyond 4GB. In such cases, existing bootmem APIs which operate on 32 bit addresses won't work and needs memblock layer which operates on 64 bit addresses. So we add equivalent APIs so that we can replace usage of bootmem with memblock interfaces. Architectures already converted to NO_BOOTMEM use these new memblock interfaces. The architectures which are still not converted to NO_BOOTMEM continue to function as is because we still maintain the fal lback option of bootmem back-end supporting these new interfaces. So no functional change as such. In long run, once all the architectures moves to NO_BOOTMEM, we can get rid of bootmem layer completely. This is one step to remove the core code dependency with bootmem and also gives path for architectures to move away from bootmem. The proposed interface will became active if both CONFIG_HAVE_MEMBLOCK and CONFIG_NO_BOOTMEM are specified by arch. In case !CONFIG_NO_BOOTMEM, the memblock() wrappers will fallback to the existing bootmem apis so that arch's not converted to NO_BOOTMEM continue to work as is. The meaning of MEMBLOCK_ALLOC_ACCESSIBLE and MEMBLOCK_ALLOC_ANYWHERE is kept same. [akpm@linux-foundation.org: s/depricated/deprecated/] Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Tejun Heo <tj@kernel.org> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Paul Walmsley <paul@pwsan.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Russell King <linux@arm.linux.org.uk> Cc: Tony Lindgren <tony@atomide.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memblock.c')
-rw-r--r--mm/memblock.c209
1 files changed, 207 insertions, 2 deletions
diff --git a/mm/memblock.c b/mm/memblock.c
index 03f1dc7b663c..018e55dc004d 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -21,6 +21,9 @@
21#include <linux/memblock.h> 21#include <linux/memblock.h>
22 22
23#include <asm-generic/sections.h> 23#include <asm-generic/sections.h>
24#include <linux/io.h>
25
26#include "internal.h"
24 27
25static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; 28static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
26static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock; 29static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
@@ -785,7 +788,7 @@ void __init_memblock __next_free_mem_range(u64 *idx, int nid,
785 bool check_node = (nid != NUMA_NO_NODE) && (nid != MAX_NUMNODES); 788 bool check_node = (nid != NUMA_NO_NODE) && (nid != MAX_NUMNODES);
786 789
787 if (nid == MAX_NUMNODES) 790 if (nid == MAX_NUMNODES)
788 pr_warn_once("%s: Usage of MAX_NUMNODES is depricated. Use NUMA_NO_NODE instead\n", 791 pr_warn_once("%s: Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n",
789 __func__); 792 __func__);
790 793
791 for ( ; mi < mem->cnt; mi++) { 794 for ( ; mi < mem->cnt; mi++) {
@@ -858,7 +861,7 @@ void __init_memblock __next_free_mem_range_rev(u64 *idx, int nid,
858 bool check_node = (nid != NUMA_NO_NODE) && (nid != MAX_NUMNODES); 861 bool check_node = (nid != NUMA_NO_NODE) && (nid != MAX_NUMNODES);
859 862
860 if (nid == MAX_NUMNODES) 863 if (nid == MAX_NUMNODES)
861 pr_warn_once("%s: Usage of MAX_NUMNODES is depricated. Use NUMA_NO_NODE instead\n", 864 pr_warn_once("%s: Usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE instead\n",
862 __func__); 865 __func__);
863 866
864 if (*idx == (u64)ULLONG_MAX) { 867 if (*idx == (u64)ULLONG_MAX) {
@@ -1029,6 +1032,208 @@ phys_addr_t __init memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, i
1029 return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE); 1032 return memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
1030} 1033}
1031 1034
1035/**
1036 * memblock_virt_alloc_internal - allocate boot memory block
1037 * @size: size of memory block to be allocated in bytes
1038 * @align: alignment of the region and block's size
1039 * @min_addr: the lower bound of the memory region to allocate (phys address)
1040 * @max_addr: the upper bound of the memory region to allocate (phys address)
1041 * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
1042 *
1043 * The @min_addr limit is dropped if it can not be satisfied and the allocation
1044 * will fall back to memory below @min_addr. Also, allocation may fall back
1045 * to any node in the system if the specified node can not
1046 * hold the requested memory.
1047 *
1048 * The allocation is performed from memory region limited by
1049 * memblock.current_limit if @max_addr == %BOOTMEM_ALLOC_ACCESSIBLE.
1050 *
1051 * The memory block is aligned on SMP_CACHE_BYTES if @align == 0.
1052 *
1053 * The phys address of allocated boot memory block is converted to virtual and
1054 * allocated memory is reset to 0.
1055 *
1056 * In addition, function sets the min_count to 0 using kmemleak_alloc for
1057 * allocated boot memory block, so that it is never reported as leaks.
1058 *
1059 * RETURNS:
1060 * Virtual address of allocated memory block on success, NULL on failure.
1061 */
1062static void * __init memblock_virt_alloc_internal(
1063 phys_addr_t size, phys_addr_t align,
1064 phys_addr_t min_addr, phys_addr_t max_addr,
1065 int nid)
1066{
1067 phys_addr_t alloc;
1068 void *ptr;
1069
1070 if (nid == MAX_NUMNODES)
1071 pr_warn("%s: usage of MAX_NUMNODES is deprecated. Use NUMA_NO_NODE\n",
1072 __func__);
1073
1074 /*
1075 * Detect any accidental use of these APIs after slab is ready, as at
1076 * this moment memblock may be deinitialized already and its
1077 * internal data may be destroyed (after execution of free_all_bootmem)
1078 */
1079 if (WARN_ON_ONCE(slab_is_available()))
1080 return kzalloc_node(size, GFP_NOWAIT, nid);
1081
1082 if (!align)
1083 align = SMP_CACHE_BYTES;
1084
1085 /* align @size to avoid excessive fragmentation on reserved array */
1086 size = round_up(size, align);
1087
1088again:
1089 alloc = memblock_find_in_range_node(size, align, min_addr, max_addr,
1090 nid);
1091 if (alloc)
1092 goto done;
1093
1094 if (nid != NUMA_NO_NODE) {
1095 alloc = memblock_find_in_range_node(size, align, min_addr,
1096 max_addr, NUMA_NO_NODE);
1097 if (alloc)
1098 goto done;
1099 }
1100
1101 if (min_addr) {
1102 min_addr = 0;
1103 goto again;
1104 } else {
1105 goto error;
1106 }
1107
1108done:
1109 memblock_reserve(alloc, size);
1110 ptr = phys_to_virt(alloc);
1111 memset(ptr, 0, size);
1112
1113 /*
1114 * The min_count is set to 0 so that bootmem allocated blocks
1115 * are never reported as leaks. This is because many of these blocks
1116 * are only referred via the physical address which is not
1117 * looked up by kmemleak.
1118 */
1119 kmemleak_alloc(ptr, size, 0, 0);
1120
1121 return ptr;
1122
1123error:
1124 return NULL;
1125}
1126
1127/**
1128 * memblock_virt_alloc_try_nid_nopanic - allocate boot memory block
1129 * @size: size of memory block to be allocated in bytes
1130 * @align: alignment of the region and block's size
1131 * @min_addr: the lower bound of the memory region from where the allocation
1132 * is preferred (phys address)
1133 * @max_addr: the upper bound of the memory region from where the allocation
1134 * is preferred (phys address), or %BOOTMEM_ALLOC_ACCESSIBLE to
1135 * allocate only from memory limited by memblock.current_limit value
1136 * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
1137 *
1138 * Public version of _memblock_virt_alloc_try_nid_nopanic() which provides
1139 * additional debug information (including caller info), if enabled.
1140 *
1141 * RETURNS:
1142 * Virtual address of allocated memory block on success, NULL on failure.
1143 */
1144void * __init memblock_virt_alloc_try_nid_nopanic(
1145 phys_addr_t size, phys_addr_t align,
1146 phys_addr_t min_addr, phys_addr_t max_addr,
1147 int nid)
1148{
1149 memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=0x%llx max_addr=0x%llx %pF\n",
1150 __func__, (u64)size, (u64)align, nid, (u64)min_addr,
1151 (u64)max_addr, (void *)_RET_IP_);
1152 return memblock_virt_alloc_internal(size, align, min_addr,
1153 max_addr, nid);
1154}
1155
1156/**
1157 * memblock_virt_alloc_try_nid - allocate boot memory block with panicking
1158 * @size: size of memory block to be allocated in bytes
1159 * @align: alignment of the region and block's size
1160 * @min_addr: the lower bound of the memory region from where the allocation
1161 * is preferred (phys address)
1162 * @max_addr: the upper bound of the memory region from where the allocation
1163 * is preferred (phys address), or %BOOTMEM_ALLOC_ACCESSIBLE to
1164 * allocate only from memory limited by memblock.current_limit value
1165 * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
1166 *
1167 * Public panicking version of _memblock_virt_alloc_try_nid_nopanic()
1168 * which provides debug information (including caller info), if enabled,
1169 * and panics if the request can not be satisfied.
1170 *
1171 * RETURNS:
1172 * Virtual address of allocated memory block on success, NULL on failure.
1173 */
1174void * __init memblock_virt_alloc_try_nid(
1175 phys_addr_t size, phys_addr_t align,
1176 phys_addr_t min_addr, phys_addr_t max_addr,
1177 int nid)
1178{
1179 void *ptr;
1180
1181 memblock_dbg("%s: %llu bytes align=0x%llx nid=%d from=0x%llx max_addr=0x%llx %pF\n",
1182 __func__, (u64)size, (u64)align, nid, (u64)min_addr,
1183 (u64)max_addr, (void *)_RET_IP_);
1184 ptr = memblock_virt_alloc_internal(size, align,
1185 min_addr, max_addr, nid);
1186 if (ptr)
1187 return ptr;
1188
1189 panic("%s: Failed to allocate %llu bytes align=0x%llx nid=%d from=0x%llx max_addr=0x%llx\n",
1190 __func__, (u64)size, (u64)align, nid, (u64)min_addr,
1191 (u64)max_addr);
1192 return NULL;
1193}
1194
1195/**
1196 * __memblock_free_early - free boot memory block
1197 * @base: phys starting address of the boot memory block
1198 * @size: size of the boot memory block in bytes
1199 *
1200 * Free boot memory block previously allocated by memblock_virt_alloc_xx() API.
1201 * The freeing memory will not be released to the buddy allocator.
1202 */
1203void __init __memblock_free_early(phys_addr_t base, phys_addr_t size)
1204{
1205 memblock_dbg("%s: [%#016llx-%#016llx] %pF\n",
1206 __func__, (u64)base, (u64)base + size - 1,
1207 (void *)_RET_IP_);
1208 kmemleak_free_part(__va(base), size);
1209 __memblock_remove(&memblock.reserved, base, size);
1210}
1211
1212/*
1213 * __memblock_free_late - free bootmem block pages directly to buddy allocator
1214 * @addr: phys starting address of the boot memory block
1215 * @size: size of the boot memory block in bytes
1216 *
1217 * This is only useful when the bootmem allocator has already been torn
1218 * down, but we are still initializing the system. Pages are released directly
1219 * to the buddy allocator, no bootmem metadata is updated because it is gone.
1220 */
1221void __init __memblock_free_late(phys_addr_t base, phys_addr_t size)
1222{
1223 u64 cursor, end;
1224
1225 memblock_dbg("%s: [%#016llx-%#016llx] %pF\n",
1226 __func__, (u64)base, (u64)base + size - 1,
1227 (void *)_RET_IP_);
1228 kmemleak_free_part(__va(base), size);
1229 cursor = PFN_UP(base);
1230 end = PFN_DOWN(base + size);
1231
1232 for (; cursor < end; cursor++) {
1233 __free_pages_bootmem(pfn_to_page(cursor), 0);
1234 totalram_pages++;
1235 }
1236}
1032 1237
1033/* 1238/*
1034 * Remaining API functions 1239 * Remaining API functions