Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d99aaa3 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds
Browse files

[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: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 805e8c03
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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++) { 
+34 −2
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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
Loading