diff options
Diffstat (limited to 'mm/bootmem.c')
| -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 51a0ccf61e0e..daf92713f7de 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
| @@ -382,7 +382,6 @@ int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | |||
| 382 | return mark_bootmem_node(pgdat->bdata, start, end, 1, flags); | 382 | return mark_bootmem_node(pgdat->bdata, start, end, 1, flags); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE | ||
| 386 | /** | 385 | /** |
| 387 | * reserve_bootmem - mark a page range as usable | 386 | * reserve_bootmem - mark a page range as usable |
| 388 | * @addr: starting address of the range | 387 | * @addr: starting address of the range |
| @@ -403,7 +402,6 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size, | |||
| 403 | 402 | ||
| 404 | return mark_bootmem(start, end, 1, flags); | 403 | return mark_bootmem(start, end, 1, flags); |
| 405 | } | 404 | } |
| 406 | #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ | ||
| 407 | 405 | ||
| 408 | static unsigned long align_idx(struct bootmem_data *bdata, unsigned long idx, | 406 | static unsigned long align_idx(struct bootmem_data *bdata, unsigned long idx, |
| 409 | unsigned long step) | 407 | unsigned long step) |
| @@ -429,8 +427,8 @@ static unsigned long align_off(struct bootmem_data *bdata, unsigned long off, | |||
| 429 | } | 427 | } |
| 430 | 428 | ||
| 431 | static void * __init alloc_bootmem_core(struct bootmem_data *bdata, | 429 | static void * __init alloc_bootmem_core(struct bootmem_data *bdata, |
| 432 | unsigned long size, unsigned long align, | 430 | unsigned long size, unsigned long align, |
| 433 | unsigned long goal, unsigned long limit) | 431 | unsigned long goal, unsigned long limit) |
| 434 | { | 432 | { |
| 435 | unsigned long fallback = 0; | 433 | unsigned long fallback = 0; |
| 436 | unsigned long min, max, start, sidx, midx, step; | 434 | unsigned long min, max, start, sidx, midx, step; |
| @@ -530,17 +528,34 @@ find_block: | |||
| 530 | return NULL; | 528 | return NULL; |
| 531 | } | 529 | } |
| 532 | 530 | ||
| 531 | static void * __init alloc_arch_preferred_bootmem(bootmem_data_t *bdata, | ||
| 532 | unsigned long size, unsigned long align, | ||
| 533 | unsigned long goal, unsigned long limit) | ||
| 534 | { | ||
| 535 | #ifdef CONFIG_HAVE_ARCH_BOOTMEM | ||
| 536 | bootmem_data_t *p_bdata; | ||
| 537 | |||
| 538 | p_bdata = bootmem_arch_preferred_node(bdata, size, align, goal, limit); | ||
| 539 | if (p_bdata) | ||
| 540 | return alloc_bootmem_core(p_bdata, size, align, goal, limit); | ||
| 541 | #endif | ||
| 542 | return NULL; | ||
| 543 | } | ||
| 544 | |||
| 533 | static void * __init ___alloc_bootmem_nopanic(unsigned long size, | 545 | static void * __init ___alloc_bootmem_nopanic(unsigned long size, |
| 534 | unsigned long align, | 546 | unsigned long align, |
| 535 | unsigned long goal, | 547 | unsigned long goal, |
| 536 | unsigned long limit) | 548 | unsigned long limit) |
| 537 | { | 549 | { |
| 538 | bootmem_data_t *bdata; | 550 | bootmem_data_t *bdata; |
| 551 | void *region; | ||
| 539 | 552 | ||
| 540 | restart: | 553 | restart: |
| 541 | list_for_each_entry(bdata, &bdata_list, list) { | 554 | region = alloc_arch_preferred_bootmem(NULL, size, align, goal, limit); |
| 542 | void *region; | 555 | if (region) |
| 556 | return region; | ||
| 543 | 557 | ||
| 558 | list_for_each_entry(bdata, &bdata_list, list) { | ||
| 544 | if (goal && bdata->node_low_pfn <= PFN_DOWN(goal)) | 559 | if (goal && bdata->node_low_pfn <= PFN_DOWN(goal)) |
| 545 | continue; | 560 | continue; |
| 546 | if (limit && bdata->node_min_pfn >= PFN_DOWN(limit)) | 561 | if (limit && bdata->node_min_pfn >= PFN_DOWN(limit)) |
| @@ -618,6 +633,10 @@ static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata, | |||
| 618 | { | 633 | { |
| 619 | void *ptr; | 634 | void *ptr; |
| 620 | 635 | ||
| 636 | ptr = alloc_arch_preferred_bootmem(bdata, size, align, goal, limit); | ||
| 637 | if (ptr) | ||
| 638 | return ptr; | ||
| 639 | |||
| 621 | ptr = alloc_bootmem_core(bdata, size, align, goal, limit); | 640 | ptr = alloc_bootmem_core(bdata, size, align, goal, limit); |
| 622 | if (ptr) | 641 | if (ptr) |
| 623 | return ptr; | 642 | return ptr; |
| @@ -674,6 +693,10 @@ void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size, | |||
| 674 | { | 693 | { |
| 675 | void *ptr; | 694 | void *ptr; |
| 676 | 695 | ||
| 696 | ptr = alloc_arch_preferred_bootmem(pgdat->bdata, size, align, goal, 0); | ||
| 697 | if (ptr) | ||
| 698 | return ptr; | ||
| 699 | |||
| 677 | ptr = alloc_bootmem_core(pgdat->bdata, size, align, goal, 0); | 700 | ptr = alloc_bootmem_core(pgdat->bdata, size, align, goal, 0); |
| 678 | if (ptr) | 701 | if (ptr) |
| 679 | return ptr; | 702 | return ptr; |
