aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-03-11 02:23:42 -0400
committerIngo Molnar <mingo@elte.hu>2008-04-26 16:51:07 -0400
commitad09315cad17458e51c7f1f8b371cb942c54b955 (patch)
tree5838f3a78b7697c0d0a7d2ae88b8424226a92067 /mm
parente123dd3f0ec1664576456ea1ea045591a0a95f0c (diff)
mm: fix alloc_bootmem_core to use fast searching for all nodes
Make the nodes other than node 0 use bdata->last_success for fast search too. We need to use __alloc_bootmem_core() for vmemmap allocation for other nodes when numa and sparsemem/vmemmap are enabled. Also, make fail_block path increase i with incr only after ALIGN to avoid extra increase when size is larger than align. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'mm')
-rw-r--r--mm/bootmem.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 2ccea700968f..3c012fb58745 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -238,28 +238,32 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
238 * We try to allocate bootmem pages above 'goal' 238 * We try to allocate bootmem pages above 'goal'
239 * first, then we try to allocate lower pages. 239 * first, then we try to allocate lower pages.
240 */ 240 */
241 if (goal && goal >= bdata->node_boot_start && PFN_DOWN(goal) < end_pfn) { 241 preferred = 0;
242 preferred = goal - bdata->node_boot_start; 242 if (goal && PFN_DOWN(goal) < end_pfn) {
243 if (goal > bdata->node_boot_start)
244 preferred = goal - bdata->node_boot_start;
243 245
244 if (bdata->last_success >= preferred) 246 if (bdata->last_success >= preferred)
245 if (!limit || (limit && limit > bdata->last_success)) 247 if (!limit || (limit && limit > bdata->last_success))
246 preferred = bdata->last_success; 248 preferred = bdata->last_success;
247 } else 249 }
248 preferred = 0;
249 250
250 preferred = PFN_DOWN(ALIGN(preferred, align)) + offset; 251 preferred = PFN_DOWN(ALIGN(preferred, align)) + offset;
251 areasize = (size + PAGE_SIZE-1) / PAGE_SIZE; 252 areasize = (size + PAGE_SIZE-1) / PAGE_SIZE;
252 incr = align >> PAGE_SHIFT ? : 1; 253 incr = align >> PAGE_SHIFT ? : 1;
253 254
254restart_scan: 255restart_scan:
255 for (i = preferred; i < eidx; i += incr) { 256 for (i = preferred; i < eidx;) {
256 unsigned long j; 257 unsigned long j;
258
257 i = find_next_zero_bit(bdata->node_bootmem_map, eidx, i); 259 i = find_next_zero_bit(bdata->node_bootmem_map, eidx, i);
258 i = ALIGN(i, incr); 260 i = ALIGN(i, incr);
259 if (i >= eidx) 261 if (i >= eidx)
260 break; 262 break;
261 if (test_bit(i, bdata->node_bootmem_map)) 263 if (test_bit(i, bdata->node_bootmem_map)) {
264 i += incr;
262 continue; 265 continue;
266 }
263 for (j = i + 1; j < i + areasize; ++j) { 267 for (j = i + 1; j < i + areasize; ++j) {
264 if (j >= eidx) 268 if (j >= eidx)
265 goto fail_block; 269 goto fail_block;
@@ -270,6 +274,8 @@ restart_scan:
270 goto found; 274 goto found;
271 fail_block: 275 fail_block:
272 i = ALIGN(j, incr); 276 i = ALIGN(j, incr);
277 if (i == j)
278 i += incr;
273 } 279 }
274 280
275 if (preferred > offset) { 281 if (preferred > offset) {