Commit fef501d49d31f997a3381b6c1efd5bca382b6b6f
1 parent
d2cd563ba8
Exists in
master
and in
20 other branches
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>
Showing 1 changed file with 16 additions and 11 deletions Side-by-side Diff
mm/memblock.c
... | ... | @@ -117,19 +117,18 @@ |
117 | 117 | return MEMBLOCK_ERROR; |
118 | 118 | } |
119 | 119 | |
120 | -static phys_addr_t __init memblock_find_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr) | |
120 | +static 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 | 123 | long i; |
123 | - phys_addr_t base = 0; | |
124 | - phys_addr_t res_base; | |
125 | 124 | |
126 | 125 | BUG_ON(0 == size); |
127 | 126 | |
128 | 127 | size = memblock_align_up(size, align); |
129 | 128 | |
130 | 129 | /* Pump up max_addr */ |
131 | - if (max_addr == MEMBLOCK_ALLOC_ACCESSIBLE) | |
132 | - max_addr = memblock.current_limit; | |
130 | + if (end == MEMBLOCK_ALLOC_ACCESSIBLE) | |
131 | + end = memblock.current_limit; | |
133 | 132 | |
134 | 133 | /* We do a top-down search, this tends to limit memory |
135 | 134 | * fragmentation by keeping early boot allocs near the |
136 | 135 | |
... | ... | @@ -138,13 +137,19 @@ |
138 | 137 | for (i = memblock.memory.cnt - 1; i >= 0; i--) { |
139 | 138 | phys_addr_t memblockbase = memblock.memory.regions[i].base; |
140 | 139 | phys_addr_t memblocksize = memblock.memory.regions[i].size; |
140 | + phys_addr_t bottom, top, found; | |
141 | 141 | |
142 | 142 | if (memblocksize < size) |
143 | 143 | continue; |
144 | - base = min(memblockbase + memblocksize, max_addr); | |
145 | - res_base = memblock_find_region(memblockbase, base, size, align); | |
146 | - if (res_base != MEMBLOCK_ERROR) | |
147 | - return res_base; | |
144 | + if ((memblockbase + memblocksize) <= start) | |
145 | + break; | |
146 | + bottom = max(memblockbase, start); | |
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 | 154 | return MEMBLOCK_ERROR; |
150 | 155 | } |
... | ... | @@ -204,7 +209,7 @@ |
204 | 209 | new_array = kmalloc(new_size, GFP_KERNEL); |
205 | 210 | addr = new_array == NULL ? MEMBLOCK_ERROR : __pa(new_array); |
206 | 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 | 213 | if (addr == MEMBLOCK_ERROR) { |
209 | 214 | pr_err("memblock: Failed to double %s array from %ld to %ld entries !\n", |
210 | 215 | memblock_type_name(type), type->max, type->max * 2); |
... | ... | @@ -416,7 +421,7 @@ |
416 | 421 | */ |
417 | 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 | 425 | if (found != MEMBLOCK_ERROR && |
421 | 426 | memblock_add_region(&memblock.reserved, found, size) >= 0) |
422 | 427 | return found; |