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@xxxxxxx> --- arch/x86_64/kernel/e820.c | 2 +- arch/x86_64/mm/init.c | 23 +++++++++++++++++++++-- drivers/acpi/Kconfig | 2 +- include/linux/init.h | 3 ++- include/linux/memory_hotplug.h | 6 ++++-- 5 files changed, 29 insertions(+), 7 deletions(-) Index: linux/arch/x86_64/mm/init.c =================================================================== --- linux.orig/arch/x86_64/mm/init.c +++ linux/arch/x86_64/mm/init.c @@ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigne /* * Memory hotplug specific functions - * These are only for non-NUMA machines right now. */ -#ifdef CONFIG_MEMORY_HOTPLUG +#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) void online_page(struct page *page) { @@ -520,6 +519,26 @@ void online_page(struct page *page) num_physpages++; } +#ifndef CONFIG_MEMORY_HOTPLUG +/* + * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, + * just online the pages. + */ +int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) +{ + int err = -EIO; + unsigned long pfn; + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + unsigned long addr = pfn << PAGE_SHIFT; + if (pfn_valid(pfn) && e820_mapped(addr, addr+1, E820_RAM)) { + online_page(pfn_to_page(pfn)); + err = 0; + } + } + return err; +} +#endif + int add_memory(u64 start, u64 size) { struct pglist_data *pgdat = NODE_DATA(0); Index: linux/drivers/acpi/Kconfig =================================================================== --- linux.orig/drivers/acpi/Kconfig +++ linux/drivers/acpi/Kconfig @@ -316,7 +316,7 @@ config ACPI_CONTAINER config ACPI_HOTPLUG_MEMORY tristate "Memory Hotplug" depends on ACPI - depends on MEMORY_HOTPLUG + depends on MEMORY_HOTPLUG || X86_64 default n help This driver adds supports for ACPI Memory Hotplug. This driver Index: linux/include/linux/memory_hotplug.h =================================================================== --- linux.orig/include/linux/memory_hotplug.h +++ linux/include/linux/memory_hotplug.h @@ -58,8 +58,6 @@ extern int add_one_highpage(struct page /* need some defines for these for archs that don't support it */ extern void online_page(struct page *page); /* VM interface that may be used by firmware interface */ -extern int add_memory(u64 start, u64 size); -extern int remove_memory(u64 start, u64 size); extern int online_pages(unsigned long, unsigned long); /* reasonably generic interface to expand the physical pages in a zone */ @@ -105,4 +103,8 @@ static inline int __remove_pages(struct dump_stack(); return -ENOSYS; } + +extern int add_memory(u64 start, u64 size); +extern int remove_memory(u64 start, u64 size); + #endif /* __LINUX_MEMORY_HOTPLUG_H */ Index: linux/include/linux/init.h =================================================================== --- linux.orig/include/linux/init.h +++ linux/include/linux/init.h @@ -241,7 +241,8 @@ void __init parse_early_param(void); #define __cpuexitdata __exitdata #endif -#ifdef CONFIG_MEMORY_HOTPLUG +#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ + || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) #define __meminit #define __meminitdata #define __memexit Index: linux/arch/x86_64/kernel/e820.c =================================================================== --- linux.orig/arch/x86_64/kernel/e820.c +++ linux/arch/x86_64/kernel/e820.c @@ -80,7 +80,7 @@ static inline int bad_addr(unsigned long return 0; } -int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) +int __meminit e820_mapped(unsigned long start, unsigned long end, unsigned type) { int i; for (i = 0; i < e820.nr_map; i++) { - : send the line "unsubscribe linux-x86_64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html