diff options
Diffstat (limited to 'mm/bootmem.c')
-rw-r--r-- | mm/bootmem.c | 18 |
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 | ||
254 | restart_scan: | 255 | restart_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) { |