diff options
author | Bernhard Walle <bwalle@suse.de> | 2008-02-07 03:15:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:25 -0500 |
commit | 72a7fe3967dbf86cb34e24fbf1d957fe24d2f246 (patch) | |
tree | c19f7d0b530577359840e959cce204939caf0649 /arch/x86 | |
parent | 25fad945a7f7ff2cf06e437381c6a1121784dbd9 (diff) |
Introduce flags for reserve_bootmem()
This patchset adds a flags variable to reserve_bootmem() and uses the
BOOTMEM_EXCLUSIVE flag in crashkernel reservation code to detect collisions
between crashkernel area and already used memory.
This patch:
Change the reserve_bootmem() function to accept a new flag BOOTMEM_EXCLUSIVE.
If that flag is set, the function returns with -EBUSY if the memory already
has been reserved in the past. This is to avoid conflicts.
Because that code runs before SMP initialisation, there's no race condition
inside reserve_bootmem_core().
[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: fix powerpc build]
Signed-off-by: Bernhard Walle <bwalle@suse.de>
Cc: <linux-arch@vger.kernel.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Vivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/mpparse_32.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 5 | ||||
-rw-r--r-- | arch/x86/mm/discontig_32.c | 3 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 4 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 5 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 3 |
7 files changed, 26 insertions, 18 deletions
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c index 67009cdd5eca..f349e68e45a0 100644 --- a/arch/x86/kernel/mpparse_32.c +++ b/arch/x86/kernel/mpparse_32.c | |||
@@ -736,7 +736,8 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) | |||
736 | smp_found_config = 1; | 736 | smp_found_config = 1; |
737 | printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n", | 737 | printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n", |
738 | mpf, virt_to_phys(mpf)); | 738 | mpf, virt_to_phys(mpf)); |
739 | reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE); | 739 | reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE, |
740 | BOOTMEM_DEFAULT); | ||
740 | if (mpf->mpf_physptr) { | 741 | if (mpf->mpf_physptr) { |
741 | /* | 742 | /* |
742 | * We cannot access to MPC table to compute | 743 | * We cannot access to MPC table to compute |
@@ -751,7 +752,8 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) | |||
751 | unsigned long end = max_low_pfn * PAGE_SIZE; | 752 | unsigned long end = max_low_pfn * PAGE_SIZE; |
752 | if (mpf->mpf_physptr + size > end) | 753 | if (mpf->mpf_physptr + size > end) |
753 | size = end - mpf->mpf_physptr; | 754 | size = end - mpf->mpf_physptr; |
754 | reserve_bootmem(mpf->mpf_physptr, size); | 755 | reserve_bootmem(mpf->mpf_physptr, size, |
756 | BOOTMEM_DEFAULT); | ||
755 | } | 757 | } |
756 | 758 | ||
757 | mpf_found = mpf; | 759 | mpf_found = mpf; |
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 62adc5f20be5..d1d8c347cc0b 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -390,7 +390,7 @@ static void __init reserve_ebda_region(void) | |||
390 | unsigned int addr; | 390 | unsigned int addr; |
391 | addr = get_bios_ebda(); | 391 | addr = get_bios_ebda(); |
392 | if (addr) | 392 | if (addr) |
393 | reserve_bootmem(addr, PAGE_SIZE); | 393 | reserve_bootmem(addr, PAGE_SIZE, BOOTMEM_DEFAULT); |
394 | } | 394 | } |
395 | 395 | ||
396 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 396 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
@@ -484,7 +484,8 @@ static void __init reserve_crashkernel(void) | |||
484 | (unsigned long)(total_mem >> 20)); | 484 | (unsigned long)(total_mem >> 20)); |
485 | crashk_res.start = crash_base; | 485 | crashk_res.start = crash_base; |
486 | crashk_res.end = crash_base + crash_size - 1; | 486 | crashk_res.end = crash_base + crash_size - 1; |
487 | reserve_bootmem(crash_base, crash_size); | 487 | reserve_bootmem(crash_base, crash_size, |
488 | BOOTMEM_DEFAULT); | ||
488 | } else | 489 | } else |
489 | printk(KERN_INFO "crashkernel reservation failed - " | 490 | printk(KERN_INFO "crashkernel reservation failed - " |
490 | "you have to specify a base address\n"); | 491 | "you have to specify a base address\n"); |
@@ -525,7 +526,7 @@ static void __init reserve_initrd(void) | |||
525 | } | 526 | } |
526 | if (ramdisk_end <= end_of_lowmem) { | 527 | if (ramdisk_end <= end_of_lowmem) { |
527 | /* All in lowmem, easy case */ | 528 | /* All in lowmem, easy case */ |
528 | reserve_bootmem(ramdisk_image, ramdisk_size); | 529 | reserve_bootmem(ramdisk_image, ramdisk_size, BOOTMEM_DEFAULT); |
529 | initrd_start = ramdisk_image + PAGE_OFFSET; | 530 | initrd_start = ramdisk_image + PAGE_OFFSET; |
530 | initrd_end = initrd_start+ramdisk_size; | 531 | initrd_end = initrd_start+ramdisk_size; |
531 | return; | 532 | return; |
@@ -536,7 +537,7 @@ static void __init reserve_initrd(void) | |||
536 | 537 | ||
537 | /* Note: this includes all the lowmem currently occupied by | 538 | /* Note: this includes all the lowmem currently occupied by |
538 | the initrd, we rely on that fact to keep the data intact. */ | 539 | the initrd, we rely on that fact to keep the data intact. */ |
539 | reserve_bootmem(ramdisk_here, ramdisk_size); | 540 | reserve_bootmem(ramdisk_here, ramdisk_size, BOOTMEM_DEFAULT); |
540 | initrd_start = ramdisk_here + PAGE_OFFSET; | 541 | initrd_start = ramdisk_here + PAGE_OFFSET; |
541 | initrd_end = initrd_start + ramdisk_size; | 542 | initrd_end = initrd_start + ramdisk_size; |
542 | 543 | ||
@@ -606,13 +607,14 @@ void __init setup_bootmem_allocator(void) | |||
606 | * bootmem allocator with an invalid RAM area. | 607 | * bootmem allocator with an invalid RAM area. |
607 | */ | 608 | */ |
608 | reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + | 609 | reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + |
609 | bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); | 610 | bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text), |
611 | BOOTMEM_DEFAULT); | ||
610 | 612 | ||
611 | /* | 613 | /* |
612 | * reserve physical page 0 - it's a special BIOS page on many boxes, | 614 | * reserve physical page 0 - it's a special BIOS page on many boxes, |
613 | * enabling clean reboots, SMP operation, laptop functions. | 615 | * enabling clean reboots, SMP operation, laptop functions. |
614 | */ | 616 | */ |
615 | reserve_bootmem(0, PAGE_SIZE); | 617 | reserve_bootmem(0, PAGE_SIZE, BOOTMEM_DEFAULT); |
616 | 618 | ||
617 | /* reserve EBDA region, it's a 4K region */ | 619 | /* reserve EBDA region, it's a 4K region */ |
618 | reserve_ebda_region(); | 620 | reserve_ebda_region(); |
@@ -622,7 +624,7 @@ void __init setup_bootmem_allocator(void) | |||
622 | unless you have no PS/2 mouse plugged in. */ | 624 | unless you have no PS/2 mouse plugged in. */ |
623 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && | 625 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && |
624 | boot_cpu_data.x86 == 6) | 626 | boot_cpu_data.x86 == 6) |
625 | reserve_bootmem(0xa0000 - 4096, 4096); | 627 | reserve_bootmem(0xa0000 - 4096, 4096, BOOTMEM_DEFAULT); |
626 | 628 | ||
627 | #ifdef CONFIG_SMP | 629 | #ifdef CONFIG_SMP |
628 | /* | 630 | /* |
@@ -630,7 +632,7 @@ void __init setup_bootmem_allocator(void) | |||
630 | * FIXME: Don't need the extra page at 4K, but need to fix | 632 | * FIXME: Don't need the extra page at 4K, but need to fix |
631 | * trampoline before removing it. (see the GDT stuff) | 633 | * trampoline before removing it. (see the GDT stuff) |
632 | */ | 634 | */ |
633 | reserve_bootmem(PAGE_SIZE, PAGE_SIZE); | 635 | reserve_bootmem(PAGE_SIZE, PAGE_SIZE, BOOTMEM_DEFAULT); |
634 | #endif | 636 | #endif |
635 | #ifdef CONFIG_ACPI_SLEEP | 637 | #ifdef CONFIG_ACPI_SLEEP |
636 | /* | 638 | /* |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index c8939dfddfba..8345c3b12f05 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -189,7 +189,7 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | |||
189 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); | 189 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); |
190 | e820_register_active_regions(0, start_pfn, end_pfn); | 190 | e820_register_active_regions(0, start_pfn, end_pfn); |
191 | free_bootmem_with_active_regions(0, end_pfn); | 191 | free_bootmem_with_active_regions(0, end_pfn); |
192 | reserve_bootmem(bootmap, bootmap_size); | 192 | reserve_bootmem(bootmap, bootmap_size, BOOTMEM_DEFAULT); |
193 | } | 193 | } |
194 | #endif | 194 | #endif |
195 | 195 | ||
@@ -238,7 +238,8 @@ static void __init reserve_crashkernel(void) | |||
238 | (unsigned long)(free_mem >> 20)); | 238 | (unsigned long)(free_mem >> 20)); |
239 | crashk_res.start = crash_base; | 239 | crashk_res.start = crash_base; |
240 | crashk_res.end = crash_base + crash_size - 1; | 240 | crashk_res.end = crash_base + crash_size - 1; |
241 | reserve_bootmem(crash_base, crash_size); | 241 | reserve_bootmem(crash_base, crash_size, |
242 | BOOTMEM_DEFAULT); | ||
242 | } else | 243 | } else |
243 | printk(KERN_INFO "crashkernel reservation failed - " | 244 | printk(KERN_INFO "crashkernel reservation failed - " |
244 | "you have to specify a base address\n"); | 245 | "you have to specify a base address\n"); |
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c index 04b1d20e2613..c394ca0720b8 100644 --- a/arch/x86/mm/discontig_32.c +++ b/arch/x86/mm/discontig_32.c | |||
@@ -391,7 +391,8 @@ unsigned long __init setup_memory(void) | |||
391 | void __init numa_kva_reserve(void) | 391 | void __init numa_kva_reserve(void) |
392 | { | 392 | { |
393 | if (kva_pages) | 393 | if (kva_pages) |
394 | reserve_bootmem(PFN_PHYS(kva_start_pfn), PFN_PHYS(kva_pages)); | 394 | reserve_bootmem(PFN_PHYS(kva_start_pfn), PFN_PHYS(kva_pages), |
395 | BOOTMEM_DEFAULT); | ||
395 | } | 396 | } |
396 | 397 | ||
397 | void __init zone_sizes_init(void) | 398 | void __init zone_sizes_init(void) |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 9b61c75a2355..5fe880fc305d 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -644,9 +644,9 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) | |||
644 | 644 | ||
645 | /* Should check here against the e820 map to avoid double free */ | 645 | /* Should check here against the e820 map to avoid double free */ |
646 | #ifdef CONFIG_NUMA | 646 | #ifdef CONFIG_NUMA |
647 | reserve_bootmem_node(NODE_DATA(nid), phys, len); | 647 | reserve_bootmem_node(NODE_DATA(nid), phys, len, BOOTMEM_DEFAULT); |
648 | #else | 648 | #else |
649 | reserve_bootmem(phys, len); | 649 | reserve_bootmem(phys, len, BOOTMEM_DEFAULT); |
650 | #endif | 650 | #endif |
651 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { | 651 | if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { |
652 | dma_reserve += len / PAGE_SIZE; | 652 | dma_reserve += len / PAGE_SIZE; |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 5a02bf4c91ec..1aecc658cd7d 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -238,9 +238,10 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, | |||
238 | 238 | ||
239 | free_bootmem_with_active_regions(nodeid, end); | 239 | free_bootmem_with_active_regions(nodeid, end); |
240 | 240 | ||
241 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); | 241 | reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size, |
242 | BOOTMEM_DEFAULT); | ||
242 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, | 243 | reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, |
243 | bootmap_pages<<PAGE_SHIFT); | 244 | bootmap_pages<<PAGE_SHIFT, BOOTMEM_DEFAULT); |
244 | #ifdef CONFIG_ACPI_NUMA | 245 | #ifdef CONFIG_ACPI_NUMA |
245 | srat_reserve_add_area(nodeid); | 246 | srat_reserve_add_area(nodeid); |
246 | #endif | 247 | #endif |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 65416f843e59..ecd91ea8a8ae 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -488,7 +488,8 @@ void __init srat_reserve_add_area(int nodeid) | |||
488 | printk(KERN_INFO "SRAT: This will cost you %Lu MB of " | 488 | printk(KERN_INFO "SRAT: This will cost you %Lu MB of " |
489 | "pre-allocated memory.\n", (unsigned long long)total_mb); | 489 | "pre-allocated memory.\n", (unsigned long long)total_mb); |
490 | reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start, | 490 | reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start, |
491 | nodes_add[nodeid].end - nodes_add[nodeid].start); | 491 | nodes_add[nodeid].end - nodes_add[nodeid].start, |
492 | BOOTMEM_DEFAULT); | ||
492 | } | 493 | } |
493 | } | 494 | } |
494 | 495 | ||