|
@@ -31,17 +31,11 @@ static nodemask_t nodes_parsed __initdata;
|
|
|
static nodemask_t cpu_nodes_parsed __initdata;
|
|
|
static struct bootnode nodes[MAX_NUMNODES] __initdata;
|
|
|
static struct bootnode nodes_add[MAX_NUMNODES];
|
|
|
-static int found_add_area __initdata;
|
|
|
-int hotadd_percent __initdata = 0;
|
|
|
|
|
|
static int num_node_memblks __initdata;
|
|
|
static struct bootnode node_memblk_range[NR_NODE_MEMBLKS] __initdata;
|
|
|
static int memblk_nodeid[NR_NODE_MEMBLKS] __initdata;
|
|
|
|
|
|
-/* Too small nodes confuse the VM badly. Usually they result
|
|
|
- from BIOS bugs. */
|
|
|
-#define NODE_MIN_SIZE (4*1024*1024)
|
|
|
-
|
|
|
static __init int setup_node(int pxm)
|
|
|
{
|
|
|
return acpi_map_pxm_to_node(pxm);
|
|
@@ -66,9 +60,6 @@ static __init void cutoff_node(int i, unsigned long start, unsigned long end)
|
|
|
{
|
|
|
struct bootnode *nd = &nodes[i];
|
|
|
|
|
|
- if (found_add_area)
|
|
|
- return;
|
|
|
-
|
|
|
if (nd->start < start) {
|
|
|
nd->start = start;
|
|
|
if (nd->end < nd->start)
|
|
@@ -86,7 +77,6 @@ static __init void bad_srat(void)
|
|
|
int i;
|
|
|
printk(KERN_ERR "SRAT: SRAT not used.\n");
|
|
|
acpi_numa = -1;
|
|
|
- found_add_area = 0;
|
|
|
for (i = 0; i < MAX_LOCAL_APIC; i++)
|
|
|
apicid_to_node[i] = NUMA_NO_NODE;
|
|
|
for (i = 0; i < MAX_NUMNODES; i++)
|
|
@@ -182,24 +172,21 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
|
|
|
pxm, apic_id, node);
|
|
|
}
|
|
|
|
|
|
-static int update_end_of_memory(unsigned long end) {return -1;}
|
|
|
-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
|
|
|
/*
|
|
|
- * Update nodes_add and decide if to include add are in the zone.
|
|
|
- * Both SPARSE and RESERVE need nodes_add information.
|
|
|
- * This code supports one contiguous hot add area per node.
|
|
|
+ * Update nodes_add[]
|
|
|
+ * This code supports one contiguous hot add area per node
|
|
|
*/
|
|
|
-static int __init
|
|
|
-reserve_hotadd(int node, unsigned long start, unsigned long end)
|
|
|
+static void __init
|
|
|
+update_nodes_add(int node, unsigned long start, unsigned long end)
|
|
|
{
|
|
|
unsigned long s_pfn = start >> PAGE_SHIFT;
|
|
|
unsigned long e_pfn = end >> PAGE_SHIFT;
|
|
|
- int ret = 0, changed = 0;
|
|
|
+ int changed = 0;
|
|
|
struct bootnode *nd = &nodes_add[node];
|
|
|
|
|
|
/* I had some trouble with strange memory hotadd regions breaking
|
|
@@ -210,7 +197,7 @@ reserve_hotadd(int node, unsigned long start, unsigned long end)
|
|
|
mistakes */
|
|
|
if ((signed long)(end - start) < NODE_MIN_SIZE) {
|
|
|
printk(KERN_ERR "SRAT: Hotplug area too small\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
/* This check might be a bit too strict, but I'm keeping it for now. */
|
|
@@ -218,12 +205,7 @@ reserve_hotadd(int node, unsigned long start, unsigned long end)
|
|
|
printk(KERN_ERR
|
|
|
"SRAT: Hotplug area %lu -> %lu has existing memory\n",
|
|
|
s_pfn, e_pfn);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (!hotadd_enough_memory(&nodes_add[node])) {
|
|
|
- printk(KERN_ERR "SRAT: Hotplug area too large\n");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
/* Looks good */
|
|
@@ -245,11 +227,9 @@ reserve_hotadd(int node, unsigned long start, unsigned long end)
|
|
|
printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
|
|
|
}
|
|
|
|
|
|
- ret = update_end_of_memory(nd->end);
|
|
|
-
|
|
|
if (changed)
|
|
|
- printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end);
|
|
|
- return ret;
|
|
|
+ printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n",
|
|
|
+ nd->start, nd->end);
|
|
|
}
|
|
|
|
|
|
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
|
|
@@ -310,13 +290,10 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
|
|
|
start, end);
|
|
|
e820_register_active_regions(node, start >> PAGE_SHIFT,
|
|
|
end >> PAGE_SHIFT);
|
|
|
- push_node_boundaries(node, nd->start >> PAGE_SHIFT,
|
|
|
- nd->end >> PAGE_SHIFT);
|
|
|
|
|
|
- if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) &&
|
|
|
- (reserve_hotadd(node, start, end) < 0)) {
|
|
|
- /* Ignore hotadd region. Undo damage */
|
|
|
- printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
|
|
|
+ if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) {
|
|
|
+ update_nodes_add(node, start, end);
|
|
|
+ /* restore nodes[node] */
|
|
|
*nd = oldnode;
|
|
|
if ((nd->start | nd->end) == 0)
|
|
|
node_clear(node, nodes_parsed);
|
|
@@ -345,9 +322,9 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
|
|
|
pxmram = 0;
|
|
|
}
|
|
|
|
|
|
- e820ram = max_pfn - absent_pages_in_range(0, max_pfn);
|
|
|
- /* We seem to lose 3 pages somewhere. Allow a bit of slack. */
|
|
|
- if ((long)(e820ram - pxmram) >= 1*1024*1024) {
|
|
|
+ e820ram = max_pfn - (e820_hole_size(0, max_pfn<<PAGE_SHIFT)>>PAGE_SHIFT);
|
|
|
+ /* We seem to lose 3 pages somewhere. Allow 1M of slack. */
|
|
|
+ if ((long)(e820ram - pxmram) >= (1<<(20 - PAGE_SHIFT))) {
|
|
|
printk(KERN_ERR
|
|
|
"SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n",
|
|
|
(pxmram << PAGE_SHIFT) >> 20,
|
|
@@ -357,17 +334,6 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-static void __init unparse_node(int node)
|
|
|
-{
|
|
|
- int i;
|
|
|
- node_clear(node, nodes_parsed);
|
|
|
- node_clear(node, cpu_nodes_parsed);
|
|
|
- for (i = 0; i < MAX_LOCAL_APIC; i++) {
|
|
|
- if (apicid_to_node[i] == node)
|
|
|
- apicid_to_node[i] = NUMA_NO_NODE;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void __init acpi_numa_arch_fixup(void) {}
|
|
|
|
|
|
/* Use the information discovered above to actually set up the nodes. */
|
|
@@ -379,18 +345,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
|
|
|
return -1;
|
|
|
|
|
|
/* First clean up the node list */
|
|
|
- for (i = 0; i < MAX_NUMNODES; i++) {
|
|
|
+ for (i = 0; i < MAX_NUMNODES; i++)
|
|
|
cutoff_node(i, start, end);
|
|
|
- /*
|
|
|
- * don't confuse VM with a node that doesn't have the
|
|
|
- * minimum memory.
|
|
|
- */
|
|
|
- if (nodes[i].end &&
|
|
|
- (nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) {
|
|
|
- unparse_node(i);
|
|
|
- node_set_offline(i);
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
if (!nodes_cover_memory(nodes)) {
|
|
|
bad_srat();
|
|
@@ -423,7 +379,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
|
|
|
|
|
|
if (node == NUMA_NO_NODE)
|
|
|
continue;
|
|
|
- if (!node_isset(node, node_possible_map))
|
|
|
+ if (!node_online(node))
|
|
|
numa_clear_node(i);
|
|
|
}
|
|
|
numa_init_array();
|
|
@@ -510,26 +466,6 @@ static int null_slit_node_compare(int a, int b)
|
|
|
}
|
|
|
#endif /* CONFIG_NUMA_EMU */
|
|
|
|
|
|
-void __init srat_reserve_add_area(int nodeid)
|
|
|
-{
|
|
|
- if (found_add_area && nodes_add[nodeid].end) {
|
|
|
- u64 total_mb;
|
|
|
-
|
|
|
- printk(KERN_INFO "SRAT: Reserving hot-add memory space "
|
|
|
- "for node %d at %Lx-%Lx\n",
|
|
|
- nodeid, nodes_add[nodeid].start, nodes_add[nodeid].end);
|
|
|
- total_mb = (nodes_add[nodeid].end - nodes_add[nodeid].start)
|
|
|
- >> PAGE_SHIFT;
|
|
|
- total_mb *= sizeof(struct page);
|
|
|
- total_mb >>= 20;
|
|
|
- printk(KERN_INFO "SRAT: This will cost you %Lu MB of "
|
|
|
- "pre-allocated memory.\n", (unsigned long long)total_mb);
|
|
|
- reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start,
|
|
|
- nodes_add[nodeid].end - nodes_add[nodeid].start,
|
|
|
- BOOTMEM_DEFAULT);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
int __node_distance(int a, int b)
|
|
|
{
|
|
|
int index;
|