forked from mirrors/linux
		
	[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>
This commit is contained in:
		
							parent
							
								
									805e8c03c9
								
							
						
					
					
						commit
						9d99aaa31f
					
				
					 6 changed files with 47 additions and 12 deletions
				
			
		|  | @ -651,6 +651,7 @@ void __init mem_init(void) | |||
|  * Specifically, in the case of x86, we will always add | ||||
|  * memory to the highmem for now. | ||||
|  */ | ||||
| #ifdef CONFIG_HOTPLUG_MEMORY | ||||
| #ifndef CONFIG_NEED_MULTIPLE_NODES | ||||
| int add_memory(u64 start, u64 size) | ||||
| { | ||||
|  | @ -667,6 +668,7 @@ int remove_memory(u64 start, u64 size) | |||
| 	return -EINVAL; | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| kmem_cache_t *pgd_cache; | ||||
| kmem_cache_t *pmd_cache; | ||||
|  |  | |||
|  | @ -80,7 +80,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) | |||
| 	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++) {  | ||||
|  |  | |||
|  | @ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) | |||
| 
 | ||||
| /*
 | ||||
|  * 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,39 @@ 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; | ||||
| 	unsigned long total = 0, mem = 0; | ||||
| 	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; | ||||
| 			mem++; | ||||
| 		} | ||||
| 		total++; | ||||
| 	} | ||||
| 	if (!err) { | ||||
| 		z->spanned_pages += total; | ||||
| 		z->present_pages += mem; | ||||
| 		z->zone_pgdat->node_spanned_pages += total; | ||||
| 		z->zone_pgdat->node_present_pages += mem; | ||||
| 	} | ||||
| 	return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Memory is added always to NORMAL zone. This means you will never get | ||||
|  * additional DMA/DMA32 memory. | ||||
|  */ | ||||
| int add_memory(u64 start, u64 size) | ||||
| { | ||||
| 	struct pglist_data *pgdat = NODE_DATA(0); | ||||
|  |  | |||
|  | @ -329,7 +329,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 | ||||
|  |  | |||
|  | @ -245,7 +245,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 | ||||
|  |  | |||
|  | @ -58,8 +58,6 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro); | |||
| /* 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  */ | ||||
|  | @ -92,11 +90,6 @@ static inline int mhp_notimplemented(const char *func) | |||
| 	return -ENOSYS; | ||||
| } | ||||
| 
 | ||||
| static inline int __add_pages(struct zone *zone, unsigned long start_pfn, | ||||
| 	unsigned long nr_pages) | ||||
| { | ||||
| 	return mhp_notimplemented(__FUNCTION__); | ||||
| } | ||||
| #endif /* ! CONFIG_MEMORY_HOTPLUG */ | ||||
| static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, | ||||
| 	unsigned long nr_pages) | ||||
|  | @ -105,4 +98,11 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, | |||
| 	dump_stack(); | ||||
| 	return -ENOSYS; | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ | ||||
| 	|| defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||||
| extern int add_memory(u64 start, u64 size); | ||||
| extern int remove_memory(u64 start, u64 size); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* __LINUX_MEMORY_HOTPLUG_H */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Andi Kleen
						Andi Kleen