Commit 71efa8fd authored by Keith Mannthey's avatar Keith Mannthey Committed by Linus Torvalds

[PATCH] hot-add-mem x86_64: Enable SPARSEMEM in srat.c

Enable x86_64 srat.c to share code between both reserve and sparsemem based
add memory paths.  Both paths need the hot-add area node locality infomration
(nodes_add).  This code refactors the code path to allow this.
Signed-off-by: default avatarKeith Mannthey <kmannth@us.ibm.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ec69acbb
...@@ -23,12 +23,6 @@ ...@@ -23,12 +23,6 @@
int acpi_numa __initdata; int acpi_numa __initdata;
#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \
defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \
&& !defined(CONFIG_MEMORY_HOTPLUG)
#define RESERVE_HOTADD 1
#endif
static struct acpi_table_slit *acpi_slit; static struct acpi_table_slit *acpi_slit;
static nodemask_t nodes_parsed __initdata; static nodemask_t nodes_parsed __initdata;
...@@ -36,9 +30,6 @@ static struct bootnode nodes[MAX_NUMNODES] __initdata; ...@@ -36,9 +30,6 @@ static struct bootnode nodes[MAX_NUMNODES] __initdata;
static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static struct bootnode nodes_add[MAX_NUMNODES] __initdata;
static int found_add_area __initdata; static int found_add_area __initdata;
int hotadd_percent __initdata = 0; int hotadd_percent __initdata = 0;
#ifndef RESERVE_HOTADD
#define hotadd_percent 0 /* Ignore all settings */
#endif
/* Too small nodes confuse the VM badly. Usually they result /* Too small nodes confuse the VM badly. Usually they result
from BIOS bugs. */ from BIOS bugs. */
...@@ -160,7 +151,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) ...@@ -160,7 +151,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
pxm, pa->apic_id, node); pxm, pa->apic_id, node);
} }
#ifdef RESERVE_HOTADD #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE
/* /*
* Protect against too large hotadd areas that would fill up memory. * Protect against too large hotadd areas that would fill up memory.
*/ */
...@@ -203,15 +194,37 @@ static int hotadd_enough_memory(struct bootnode *nd) ...@@ -203,15 +194,37 @@ static int hotadd_enough_memory(struct bootnode *nd)
return 1; return 1;
} }
static int update_end_of_memory(unsigned long end)
{
found_add_area = 1;
if ((end >> PAGE_SHIFT) > end_pfn)
end_pfn = end >> PAGE_SHIFT;
return 1;
}
static inline int save_add_info(void)
{
return hotadd_percent > 0;
}
#else
int update_end_of_memory(unsigned long end) {return 0;}
static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
static inline int save_add_info(void) {return 1;}
#else
static inline int save_add_info(void) {return 0;}
#endif
#endif
/* /*
* It is fine to add this area to the nodes data it will be used later * Update nodes_add and decide if to include add are in the zone.
* Both SPARSE and RESERVE need nodes_add infomation.
* This code supports one contigious hot add area per node. * This code supports one contigious hot add area per node.
*/ */
static int reserve_hotadd(int node, unsigned long start, unsigned long end) static int reserve_hotadd(int node, unsigned long start, unsigned long end)
{ {
unsigned long s_pfn = start >> PAGE_SHIFT; unsigned long s_pfn = start >> PAGE_SHIFT;
unsigned long e_pfn = end >> PAGE_SHIFT; unsigned long e_pfn = end >> PAGE_SHIFT;
int changed = 0; int ret = 0, changed = 0;
struct bootnode *nd = &nodes_add[node]; struct bootnode *nd = &nodes_add[node];
/* I had some trouble with strange memory hotadd regions breaking /* I had some trouble with strange memory hotadd regions breaking
...@@ -240,7 +253,6 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) ...@@ -240,7 +253,6 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
/* Looks good */ /* Looks good */
found_add_area = 1;
if (nd->start == nd->end) { if (nd->start == nd->end) {
nd->start = start; nd->start = start;
nd->end = end; nd->end = end;
...@@ -258,14 +270,12 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) ...@@ -258,14 +270,12 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
} }
if ((nd->end >> PAGE_SHIFT) > end_pfn) ret = update_end_of_memory(nd->end);
end_pfn = nd->end >> PAGE_SHIFT;
if (changed) if (changed)
printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end);
return 0; return ret;
} }
#endif
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
void __init void __init
...@@ -284,7 +294,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) ...@@ -284,7 +294,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
} }
if (ma->flags.enabled == 0) if (ma->flags.enabled == 0)
return; return;
if (ma->flags.hot_pluggable && hotadd_percent == 0) if (ma->flags.hot_pluggable && !save_add_info())
return; return;
start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
...@@ -327,15 +337,13 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) ...@@ -327,15 +337,13 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
push_node_boundaries(node, nd->start >> PAGE_SHIFT, push_node_boundaries(node, nd->start >> PAGE_SHIFT,
nd->end >> PAGE_SHIFT); nd->end >> PAGE_SHIFT);
#ifdef RESERVE_HOTADD if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) {
/* Ignore hotadd region. Undo damage */ /* Ignore hotadd region. Undo damage */
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
*nd = oldnode; *nd = oldnode;
if ((nd->start | nd->end) == 0) if ((nd->start | nd->end) == 0)
node_clear(node, nodes_parsed); node_clear(node, nodes_parsed);
} }
#endif
} }
/* Sanity check to catch more bad SRATs (they are amazingly common). /* Sanity check to catch more bad SRATs (they are amazingly common).
...@@ -351,7 +359,6 @@ static int nodes_cover_memory(void) ...@@ -351,7 +359,6 @@ static int nodes_cover_memory(void)
unsigned long e = nodes[i].end >> PAGE_SHIFT; unsigned long e = nodes[i].end >> PAGE_SHIFT;
pxmram += e - s; pxmram += e - s;
pxmram -= absent_pages_in_range(s, e); pxmram -= absent_pages_in_range(s, e);
pxmram -= nodes_add[i].end - nodes_add[i].start;
if ((long)pxmram < 0) if ((long)pxmram < 0)
pxmram = 0; pxmram = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment