diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-11-22 20:18:49 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-23 03:09:23 -0500 |
commit | 44280733e71ad15377735b42d8538c109c94d7e3 (patch) | |
tree | 0b549984cf93f0e25fd49c21187cc8a6b49cddba /arch/x86/kernel/setup.c | |
parent | 350f8f5631922c7848ec4b530c111cb8c2ff7caa (diff) |
x86: Change crash kernel to reserve via reserve_early()
use find_e820_area()/reserve_early() instead.
-v2: address Eric's request, to restore original semantics.
will fail, if the provided address can not be used.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Eric W. Biederman <ebiederm@xmission.com>
LKML-Reference: <4B09E2F9.7040403@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r-- | arch/x86/kernel/setup.c | 57 |
1 files changed, 15 insertions, 42 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index d2043a00abc1..e3eae5965e4a 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -487,42 +487,11 @@ static void __init reserve_early_setup_data(void) | |||
487 | 487 | ||
488 | #ifdef CONFIG_KEXEC | 488 | #ifdef CONFIG_KEXEC |
489 | 489 | ||
490 | /** | ||
491 | * Reserve @size bytes of crashkernel memory at any suitable offset. | ||
492 | * | ||
493 | * @size: Size of the crashkernel memory to reserve. | ||
494 | * Returns the base address on success, and -1ULL on failure. | ||
495 | */ | ||
496 | static | ||
497 | unsigned long long __init find_and_reserve_crashkernel(unsigned long long size) | ||
498 | { | ||
499 | const unsigned long long alignment = 16<<20; /* 16M */ | ||
500 | unsigned long long start = 0LL; | ||
501 | |||
502 | while (1) { | ||
503 | int ret; | ||
504 | |||
505 | start = find_e820_area(start, ULONG_MAX, size, alignment); | ||
506 | if (start == -1ULL) | ||
507 | return start; | ||
508 | |||
509 | /* try to reserve it */ | ||
510 | ret = reserve_bootmem_generic(start, size, BOOTMEM_EXCLUSIVE); | ||
511 | if (ret >= 0) | ||
512 | return start; | ||
513 | |||
514 | start += alignment; | ||
515 | } | ||
516 | } | ||
517 | |||
518 | static inline unsigned long long get_total_mem(void) | 490 | static inline unsigned long long get_total_mem(void) |
519 | { | 491 | { |
520 | unsigned long long total; | 492 | unsigned long long total; |
521 | 493 | ||
522 | total = max_low_pfn - min_low_pfn; | 494 | total = max_pfn - min_low_pfn; |
523 | #ifdef CONFIG_HIGHMEM | ||
524 | total += highend_pfn - highstart_pfn; | ||
525 | #endif | ||
526 | 495 | ||
527 | return total << PAGE_SHIFT; | 496 | return total << PAGE_SHIFT; |
528 | } | 497 | } |
@@ -542,21 +511,25 @@ static void __init reserve_crashkernel(void) | |||
542 | 511 | ||
543 | /* 0 means: find the address automatically */ | 512 | /* 0 means: find the address automatically */ |
544 | if (crash_base <= 0) { | 513 | if (crash_base <= 0) { |
545 | crash_base = find_and_reserve_crashkernel(crash_size); | 514 | const unsigned long long alignment = 16<<20; /* 16M */ |
515 | |||
516 | crash_base = find_e820_area(alignment, ULONG_MAX, crash_size, | ||
517 | alignment); | ||
546 | if (crash_base == -1ULL) { | 518 | if (crash_base == -1ULL) { |
547 | pr_info("crashkernel reservation failed. " | 519 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
548 | "No suitable area found.\n"); | ||
549 | return; | 520 | return; |
550 | } | 521 | } |
551 | } else { | 522 | } else { |
552 | ret = reserve_bootmem_generic(crash_base, crash_size, | 523 | unsigned long long start; |
553 | BOOTMEM_EXCLUSIVE); | 524 | |
554 | if (ret < 0) { | 525 | start = find_e820_area(crash_base, ULONG_MAX, crash_size, |
555 | pr_info("crashkernel reservation failed - " | 526 | 1<<20); |
556 | "memory is in use\n"); | 527 | if (start != crash_base) { |
528 | pr_info("crashkernel reservation failed - memory is in use.\n"); | ||
557 | return; | 529 | return; |
558 | } | 530 | } |
559 | } | 531 | } |
532 | reserve_early(crash_base, crash_base + crash_size, "CRASH KERNEL"); | ||
560 | 533 | ||
561 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | 534 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " |
562 | "for crashkernel (System RAM: %ldMB)\n", | 535 | "for crashkernel (System RAM: %ldMB)\n", |
@@ -927,6 +900,8 @@ void __init setup_arch(char **cmdline_p) | |||
927 | 900 | ||
928 | reserve_initrd(); | 901 | reserve_initrd(); |
929 | 902 | ||
903 | reserve_crashkernel(); | ||
904 | |||
930 | vsmp_init(); | 905 | vsmp_init(); |
931 | 906 | ||
932 | io_delay_init(); | 907 | io_delay_init(); |
@@ -957,8 +932,6 @@ void __init setup_arch(char **cmdline_p) | |||
957 | */ | 932 | */ |
958 | find_smp_config(); | 933 | find_smp_config(); |
959 | 934 | ||
960 | reserve_crashkernel(); | ||
961 | |||
962 | #ifdef CONFIG_X86_64 | 935 | #ifdef CONFIG_X86_64 |
963 | /* | 936 | /* |
964 | * dma32_reserve_bootmem() allocates bootmem which may conflict | 937 | * dma32_reserve_bootmem() allocates bootmem which may conflict |