diff options
author | Andi Kleen <ak@suse.de> | 2006-04-07 13:49:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-09 14:53:16 -0400 |
commit | 9d99aaa31f5994d1923c3713ce9144c4c42332e1 (patch) | |
tree | ae608593ca196dd6493cccbdfc1b8dd098e91ee8 /arch | |
parent | 805e8c03c9ea9bdb402a36341e02ec24825d5417 (diff) |
[PATCH] x86_64: Support memory hotadd without sparsemem
Memory hotadd doesn't need SPARSEMEM, but can be handled by just preallocating
mem_maps. This only needs some untangling of ifdefs to enable the necessary
code even without SPARSEMEM.
Originally from Keith Mannthey, hacked by AK.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/mm/init.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/e820.c | 2 | ||||
-rw-r--r-- | arch/x86_64/mm/init.c | 36 |
3 files changed, 37 insertions, 3 deletions
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 9f66ac582a8b..ae6534ad8161 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -651,6 +651,7 @@ void __init mem_init(void) | |||
651 | * Specifically, in the case of x86, we will always add | 651 | * Specifically, in the case of x86, we will always add |
652 | * memory to the highmem for now. | 652 | * memory to the highmem for now. |
653 | */ | 653 | */ |
654 | #ifdef CONFIG_HOTPLUG_MEMORY | ||
654 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 655 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
655 | int add_memory(u64 start, u64 size) | 656 | int add_memory(u64 start, u64 size) |
656 | { | 657 | { |
@@ -667,6 +668,7 @@ int remove_memory(u64 start, u64 size) | |||
667 | return -EINVAL; | 668 | return -EINVAL; |
668 | } | 669 | } |
669 | #endif | 670 | #endif |
671 | #endif | ||
670 | 672 | ||
671 | kmem_cache_t *pgd_cache; | 673 | kmem_cache_t *pgd_cache; |
672 | kmem_cache_t *pmd_cache; | 674 | kmem_cache_t *pmd_cache; |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 293cd71a266a..db57d3ff04e3 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -80,7 +80,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) | 83 | int __meminit e820_mapped(unsigned long start, unsigned long end, unsigned type) |
84 | { | 84 | { |
85 | int i; | 85 | int i; |
86 | for (i = 0; i < e820.nr_map; i++) { | 86 | for (i = 0; i < e820.nr_map; i++) { |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index e5f7f1c34462..492161168402 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
507 | 507 | ||
508 | /* | 508 | /* |
509 | * Memory hotplug specific functions | 509 | * Memory hotplug specific functions |
510 | * These are only for non-NUMA machines right now. | ||
511 | */ | 510 | */ |
512 | #ifdef CONFIG_MEMORY_HOTPLUG | 511 | #if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) |
513 | 512 | ||
514 | void online_page(struct page *page) | 513 | void online_page(struct page *page) |
515 | { | 514 | { |
@@ -520,6 +519,39 @@ void online_page(struct page *page) | |||
520 | num_physpages++; | 519 | num_physpages++; |
521 | } | 520 | } |
522 | 521 | ||
522 | #ifndef CONFIG_MEMORY_HOTPLUG | ||
523 | /* | ||
524 | * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, | ||
525 | * just online the pages. | ||
526 | */ | ||
527 | int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) | ||
528 | { | ||
529 | int err = -EIO; | ||
530 | unsigned long pfn; | ||
531 | unsigned long total = 0, mem = 0; | ||
532 | for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { | ||
533 | unsigned long addr = pfn << PAGE_SHIFT; | ||
534 | if (pfn_valid(pfn) && e820_mapped(addr, addr+1, E820_RAM)) { | ||
535 | online_page(pfn_to_page(pfn)); | ||
536 | err = 0; | ||
537 | mem++; | ||
538 | } | ||
539 | total++; | ||
540 | } | ||
541 | if (!err) { | ||
542 | z->spanned_pages += total; | ||
543 | z->present_pages += mem; | ||
544 | z->zone_pgdat->node_spanned_pages += total; | ||
545 | z->zone_pgdat->node_present_pages += mem; | ||
546 | } | ||
547 | return err; | ||
548 | } | ||
549 | #endif | ||
550 | |||
551 | /* | ||
552 | * Memory is added always to NORMAL zone. This means you will never get | ||
553 | * additional DMA/DMA32 memory. | ||
554 | */ | ||
523 | int add_memory(u64 start, u64 size) | 555 | int add_memory(u64 start, u64 size) |
524 | { | 556 | { |
525 | struct pglist_data *pgdat = NODE_DATA(0); | 557 | struct pglist_data *pgdat = NODE_DATA(0); |