aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memblock.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-12 01:00:34 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-08-04 22:56:22 -0400
commitfef501d49d31f997a3381b6c1efd5bca382b6b6f (patch)
treed228dd686367dd3a49fc4152cef94d83b99dad29 /mm/memblock.c
parentd2cd563ba82c424083b78e0ce97d68bfb04d1242 (diff)
memblock: Add "start" argument to memblock_find_base()
To constraint the search of a region between two boundaries, which will be used by the new NUMA aware allocator among others. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'mm/memblock.c')
-rw-r--r--mm/memblock.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/mm/memblock.c b/mm/memblock.c
index 8715f09434df..468ff43a72b4 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -117,19 +117,18 @@ static phys_addr_t __init memblock_find_region(phys_addr_t start, phys_addr_t en
117 return MEMBLOCK_ERROR; 117 return MEMBLOCK_ERROR;
118} 118}
119 119
120static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr) 120static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t align,
121 phys_addr_t start, phys_addr_t end)
121{ 122{
122 long i; 123 long i;
123 phys_addr_t base = 0;
124 phys_addr_t res_base;
125 124
126 BUG_ON(0 == size); 125 BUG_ON(0 == size);
127 126
128 size = memblock_align_up(size, align); 127 size = memblock_align_up(size, align);
129 128
130 /* Pump up max_addr */ 129 /* Pump up max_addr */
131 if (max_addr == MEMBLOCK_ALLOC_ACCESSIBLE) 130 if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
132 max_addr = memblock.current_limit; 131 end = memblock.current_limit;
133 132
134 /* We do a top-down search, this tends to limit memory 133 /* We do a top-down search, this tends to limit memory
135 * fragmentation by keeping early boot allocs near the 134 * fragmentation by keeping early boot allocs near the
@@ -138,13 +137,19 @@ static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t align
138 for (i = memblock.memory.cnt - 1; i >= 0; i--) { 137 for (i = memblock.memory.cnt - 1; i >= 0; i--) {
139 phys_addr_t memblockbase = memblock.memory.regions[i].base; 138 phys_addr_t memblockbase = memblock.memory.regions[i].base;
140 phys_addr_t memblocksize = memblock.memory.regions[i].size; 139 phys_addr_t memblocksize = memblock.memory.regions[i].size;
140 phys_addr_t bottom, top, found;
141 141
142 if (memblocksize < size) 142 if (memblocksize < size)
143 continue; 143 continue;
144 base = min(memblockbase + memblocksize, max_addr); 144 if ((memblockbase + memblocksize) <= start)
145 res_base = memblock_find_region(memblockbase, base, size, align); 145 break;
146 if (res_base != MEMBLOCK_ERROR) 146 bottom = max(memblockbase, start);
147 return res_base; 147 top = min(memblockbase + memblocksize, end);
148 if (bottom >= top)
149 continue;
150 found = memblock_find_region(bottom, top, size, align);
151 if (found != MEMBLOCK_ERROR)
152 return found;
148 } 153 }
149 return MEMBLOCK_ERROR; 154 return MEMBLOCK_ERROR;
150} 155}
@@ -204,7 +209,7 @@ static int memblock_double_array(struct memblock_type *type)
204 new_array = kmalloc(new_size, GFP_KERNEL); 209 new_array = kmalloc(new_size, GFP_KERNEL);
205 addr = new_array == NULL ? MEMBLOCK_ERROR : __pa(new_array); 210 addr = new_array == NULL ? MEMBLOCK_ERROR : __pa(new_array);
206 } else 211 } else
207 addr = memblock_find_base(new_size, sizeof(phys_addr_t), MEMBLOCK_ALLOC_ACCESSIBLE); 212 addr = memblock_find_base(new_size, sizeof(phys_addr_t), 0, MEMBLOCK_ALLOC_ACCESSIBLE);
208 if (addr == MEMBLOCK_ERROR) { 213 if (addr == MEMBLOCK_ERROR) {
209 pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n", 214 pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n",
210 memblock_type_name(type), type->max, type->max * 2); 215 memblock_type_name(type), type->max, type->max * 2);
@@ -416,7 +421,7 @@ phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, ph
416 */ 421 */
417 size = memblock_align_up(size, align); 422 size = memblock_align_up(size, align);
418 423
419 found = memblock_find_base(size, align, max_addr); 424 found = memblock_find_base(size, align, 0, max_addr);
420 if (found != MEMBLOCK_ERROR && 425 if (found != MEMBLOCK_ERROR &&
421 memblock_add_region(&memblock.reserved, found, size) >= 0) 426 memblock_add_region(&memblock.reserved, found, size) >= 0)
422 return found; 427 return found;