diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/bootmem.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/mm/bootmem.c b/mm/bootmem.c index e023c68b0255..ad8eec6e44a8 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -405,6 +405,29 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size, | |||
405 | } | 405 | } |
406 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ | 406 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ |
407 | 407 | ||
408 | static unsigned long align_idx(struct bootmem_data *bdata, unsigned long idx, | ||
409 | unsigned long step) | ||
410 | { | ||
411 | unsigned long base = bdata->node_min_pfn; | ||
412 | |||
413 | /* | ||
414 | * Align the index with respect to the node start so that the | ||
415 | * combination of both satisfies the requested alignment. | ||
416 | */ | ||
417 | |||
418 | return ALIGN(base + idx, step) - base; | ||
419 | } | ||
420 | |||
421 | static unsigned long align_off(struct bootmem_data *bdata, unsigned long off, | ||
422 | unsigned long align) | ||
423 | { | ||
424 | unsigned long base = PFN_PHYS(bdata->node_min_pfn); | ||
425 | |||
426 | /* Same as align_idx for byte offsets */ | ||
427 | |||
428 | return ALIGN(base + off, align) - base; | ||
429 | } | ||
430 | |||
408 | static void * __init alloc_bootmem_core(struct bootmem_data *bdata, | 431 | static void * __init alloc_bootmem_core(struct bootmem_data *bdata, |
409 | unsigned long size, unsigned long align, | 432 | unsigned long size, unsigned long align, |
410 | unsigned long goal, unsigned long limit) | 433 | unsigned long goal, unsigned long limit) |
@@ -441,7 +464,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata, | |||
441 | else | 464 | else |
442 | start = ALIGN(min, step); | 465 | start = ALIGN(min, step); |
443 | 466 | ||
444 | sidx = start - bdata->node_min_pfn;; | 467 | sidx = start - bdata->node_min_pfn; |
445 | midx = max - bdata->node_min_pfn; | 468 | midx = max - bdata->node_min_pfn; |
446 | 469 | ||
447 | if (bdata->hint_idx > sidx) { | 470 | if (bdata->hint_idx > sidx) { |
@@ -450,7 +473,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata, | |||
450 | * catch the fallback below. | 473 | * catch the fallback below. |
451 | */ | 474 | */ |
452 | fallback = sidx + 1; | 475 | fallback = sidx + 1; |
453 | sidx = ALIGN(bdata->hint_idx, step); | 476 | sidx = align_idx(bdata, bdata->hint_idx, step); |
454 | } | 477 | } |
455 | 478 | ||
456 | while (1) { | 479 | while (1) { |
@@ -459,7 +482,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata, | |||
459 | unsigned long eidx, i, start_off, end_off; | 482 | unsigned long eidx, i, start_off, end_off; |
460 | find_block: | 483 | find_block: |
461 | sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx); | 484 | sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx); |
462 | sidx = ALIGN(sidx, step); | 485 | sidx = align_idx(bdata, sidx, step); |
463 | eidx = sidx + PFN_UP(size); | 486 | eidx = sidx + PFN_UP(size); |
464 | 487 | ||
465 | if (sidx >= midx || eidx > midx) | 488 | if (sidx >= midx || eidx > midx) |
@@ -467,7 +490,7 @@ find_block: | |||
467 | 490 | ||
468 | for (i = sidx; i < eidx; i++) | 491 | for (i = sidx; i < eidx; i++) |
469 | if (test_bit(i, bdata->node_bootmem_map)) { | 492 | if (test_bit(i, bdata->node_bootmem_map)) { |
470 | sidx = ALIGN(i, step); | 493 | sidx = align_idx(bdata, i, step); |
471 | if (sidx == i) | 494 | if (sidx == i) |
472 | sidx += step; | 495 | sidx += step; |
473 | goto find_block; | 496 | goto find_block; |
@@ -475,7 +498,7 @@ find_block: | |||
475 | 498 | ||
476 | if (bdata->last_end_off & (PAGE_SIZE - 1) && | 499 | if (bdata->last_end_off & (PAGE_SIZE - 1) && |
477 | PFN_DOWN(bdata->last_end_off) + 1 == sidx) | 500 | PFN_DOWN(bdata->last_end_off) + 1 == sidx) |
478 | start_off = ALIGN(bdata->last_end_off, align); | 501 | start_off = align_off(bdata, bdata->last_end_off, align); |
479 | else | 502 | else |
480 | start_off = PFN_PHYS(sidx); | 503 | start_off = PFN_PHYS(sidx); |
481 | 504 | ||
@@ -499,7 +522,7 @@ find_block: | |||
499 | } | 522 | } |
500 | 523 | ||
501 | if (fallback) { | 524 | if (fallback) { |
502 | sidx = ALIGN(fallback - 1, step); | 525 | sidx = align_idx(bdata, fallback - 1, step); |
503 | fallback = 0; | 526 | fallback = 0; |
504 | goto find_block; | 527 | goto find_block; |
505 | } | 528 | } |