diff options
| -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) { |
