aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-04-07 13:49:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-09 14:53:16 -0400
commit9d99aaa31f5994d1923c3713ce9144c4c42332e1 (patch)
treeae608593ca196dd6493cccbdfc1b8dd098e91ee8
parent805e8c03c9ea9bdb402a36341e02ec24825d5417 (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>
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/x86_64/kernel/e820.c2
-rw-r--r--arch/x86_64/mm/init.c36
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--include/linux/init.h3
-rw-r--r--include/linux/memory_hotplug.h14
6 files changed, 47 insertions, 12 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
655int add_memory(u64 start, u64 size) 656int 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
671kmem_cache_t *pgd_cache; 673kmem_cache_t *pgd_cache;
672kmem_cache_t *pmd_cache; 674kmem_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
83int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) 83int __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
514void online_page(struct page *page) 513void 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 */
527int __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 */
523int add_memory(u64 start, u64 size) 555int add_memory(u64 start, u64 size)
524{ 556{
525 struct pglist_data *pgdat = NODE_DATA(0); 557 struct pglist_data *pgdat = NODE_DATA(0);
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 5cb96300eb0f..c24652d31bf9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -329,7 +329,7 @@ config ACPI_CONTAINER
329config ACPI_HOTPLUG_MEMORY 329config ACPI_HOTPLUG_MEMORY
330 tristate "Memory Hotplug" 330 tristate "Memory Hotplug"
331 depends on ACPI 331 depends on ACPI
332 depends on MEMORY_HOTPLUG 332 depends on MEMORY_HOTPLUG || X86_64
333 default n 333 default n
334 help 334 help
335 This driver adds supports for ACPI Memory Hotplug. This driver 335 This driver adds supports for ACPI Memory Hotplug. This driver
diff --git a/include/linux/init.h b/include/linux/init.h
index ed0ac7c39fdc..93dcbe1abb4c 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -245,7 +245,8 @@ void __init parse_early_param(void);
245#define __cpuexitdata __exitdata 245#define __cpuexitdata __exitdata
246#endif 246#endif
247 247
248#ifdef CONFIG_MEMORY_HOTPLUG 248#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
249 || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
249#define __meminit 250#define __meminit
250#define __meminitdata 251#define __meminitdata
251#define __memexit 252#define __memexit
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 968b1aa3732c..4ca3e6ad03ec 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -58,8 +58,6 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
58/* need some defines for these for archs that don't support it */ 58/* need some defines for these for archs that don't support it */
59extern void online_page(struct page *page); 59extern void online_page(struct page *page);
60/* VM interface that may be used by firmware interface */ 60/* VM interface that may be used by firmware interface */
61extern int add_memory(u64 start, u64 size);
62extern int remove_memory(u64 start, u64 size);
63extern int online_pages(unsigned long, unsigned long); 61extern int online_pages(unsigned long, unsigned long);
64 62
65/* reasonably generic interface to expand the physical pages in a zone */ 63/* reasonably generic interface to expand the physical pages in a zone */
@@ -92,11 +90,6 @@ static inline int mhp_notimplemented(const char *func)
92 return -ENOSYS; 90 return -ENOSYS;
93} 91}
94 92
95static inline int __add_pages(struct zone *zone, unsigned long start_pfn,
96 unsigned long nr_pages)
97{
98 return mhp_notimplemented(__FUNCTION__);
99}
100#endif /* ! CONFIG_MEMORY_HOTPLUG */ 93#endif /* ! CONFIG_MEMORY_HOTPLUG */
101static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, 94static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
102 unsigned long nr_pages) 95 unsigned long nr_pages)
@@ -105,4 +98,11 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
105 dump_stack(); 98 dump_stack();
106 return -ENOSYS; 99 return -ENOSYS;
107} 100}
101
102#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
103 || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
104extern int add_memory(u64 start, u64 size);
105extern int remove_memory(u64 start, u64 size);
106#endif
107
108#endif /* __LINUX_MEMORY_HOTPLUG_H */ 108#endif /* __LINUX_MEMORY_HOTPLUG_H */