diff options
Diffstat (limited to 'arch/x86/mm/srat_64.c')
-rw-r--r-- | arch/x86/mm/srat_64.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index dbb5381f7b3b..38512d0c4742 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -136,7 +136,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) | |||
136 | apicid_to_node[apic_id] = node; | 136 | apicid_to_node[apic_id] = node; |
137 | node_set(node, cpu_nodes_parsed); | 137 | node_set(node, cpu_nodes_parsed); |
138 | acpi_numa = 1; | 138 | acpi_numa = 1; |
139 | printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", | 139 | printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", |
140 | pxm, apic_id, node); | 140 | pxm, apic_id, node); |
141 | } | 141 | } |
142 | 142 | ||
@@ -170,7 +170,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) | |||
170 | apicid_to_node[apic_id] = node; | 170 | apicid_to_node[apic_id] = node; |
171 | node_set(node, cpu_nodes_parsed); | 171 | node_set(node, cpu_nodes_parsed); |
172 | acpi_numa = 1; | 172 | acpi_numa = 1; |
173 | printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", | 173 | printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", |
174 | pxm, apic_id, node); | 174 | pxm, apic_id, node); |
175 | } | 175 | } |
176 | 176 | ||
@@ -229,9 +229,11 @@ update_nodes_add(int node, unsigned long start, unsigned long end) | |||
229 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); | 229 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); |
230 | } | 230 | } |
231 | 231 | ||
232 | if (changed) | 232 | if (changed) { |
233 | node_set(node, cpu_nodes_parsed); | ||
233 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", | 234 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", |
234 | nd->start, nd->end); | 235 | nd->start, nd->end); |
236 | } | ||
235 | } | 237 | } |
236 | 238 | ||
237 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 239 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
@@ -290,8 +292,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
290 | 292 | ||
291 | printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm, | 293 | printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm, |
292 | start, end); | 294 | start, end); |
293 | e820_register_active_regions(node, start >> PAGE_SHIFT, | ||
294 | end >> PAGE_SHIFT); | ||
295 | 295 | ||
296 | if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) { | 296 | if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) { |
297 | update_nodes_add(node, start, end); | 297 | update_nodes_add(node, start, end); |
@@ -319,7 +319,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) | |||
319 | unsigned long s = nodes[i].start >> PAGE_SHIFT; | 319 | unsigned long s = nodes[i].start >> PAGE_SHIFT; |
320 | unsigned long e = nodes[i].end >> PAGE_SHIFT; | 320 | unsigned long e = nodes[i].end >> PAGE_SHIFT; |
321 | pxmram += e - s; | 321 | pxmram += e - s; |
322 | pxmram -= absent_pages_in_range(s, e); | 322 | pxmram -= __absent_pages_in_range(i, s, e); |
323 | if ((long)pxmram < 0) | 323 | if ((long)pxmram < 0) |
324 | pxmram = 0; | 324 | pxmram = 0; |
325 | } | 325 | } |
@@ -338,6 +338,19 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) | |||
338 | 338 | ||
339 | void __init acpi_numa_arch_fixup(void) {} | 339 | void __init acpi_numa_arch_fixup(void) {} |
340 | 340 | ||
341 | int __init acpi_get_nodes(struct bootnode *physnodes) | ||
342 | { | ||
343 | int i; | ||
344 | int ret = 0; | ||
345 | |||
346 | for_each_node_mask(i, nodes_parsed) { | ||
347 | physnodes[ret].start = nodes[i].start; | ||
348 | physnodes[ret].end = nodes[i].end; | ||
349 | ret++; | ||
350 | } | ||
351 | return ret; | ||
352 | } | ||
353 | |||
341 | /* Use the information discovered above to actually set up the nodes. */ | 354 | /* Use the information discovered above to actually set up the nodes. */ |
342 | int __init acpi_scan_nodes(unsigned long start, unsigned long end) | 355 | int __init acpi_scan_nodes(unsigned long start, unsigned long end) |
343 | { | 356 | { |
@@ -350,11 +363,6 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
350 | for (i = 0; i < MAX_NUMNODES; i++) | 363 | for (i = 0; i < MAX_NUMNODES; i++) |
351 | cutoff_node(i, start, end); | 364 | cutoff_node(i, start, end); |
352 | 365 | ||
353 | if (!nodes_cover_memory(nodes)) { | ||
354 | bad_srat(); | ||
355 | return -1; | ||
356 | } | ||
357 | |||
358 | memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks, | 366 | memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks, |
359 | memblk_nodeid); | 367 | memblk_nodeid); |
360 | if (memnode_shift < 0) { | 368 | if (memnode_shift < 0) { |
@@ -364,6 +372,16 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
364 | return -1; | 372 | return -1; |
365 | } | 373 | } |
366 | 374 | ||
375 | for_each_node_mask(i, nodes_parsed) | ||
376 | e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, | ||
377 | nodes[i].end >> PAGE_SHIFT); | ||
378 | /* for out of order entries in SRAT */ | ||
379 | sort_node_map(); | ||
380 | if (!nodes_cover_memory(nodes)) { | ||
381 | bad_srat(); | ||
382 | return -1; | ||
383 | } | ||
384 | |||
367 | /* Account for nodes with cpus and no memory */ | 385 | /* Account for nodes with cpus and no memory */ |
368 | nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed); | 386 | nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed); |
369 | 387 | ||
@@ -443,7 +461,8 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) | |||
443 | * node, it must now point to the fake node ID. | 461 | * node, it must now point to the fake node ID. |
444 | */ | 462 | */ |
445 | for (j = 0; j < MAX_LOCAL_APIC; j++) | 463 | for (j = 0; j < MAX_LOCAL_APIC; j++) |
446 | if (apicid_to_node[j] == nid) | 464 | if (apicid_to_node[j] == nid && |
465 | fake_apicid_to_node[j] == NUMA_NO_NODE) | ||
447 | fake_apicid_to_node[j] = i; | 466 | fake_apicid_to_node[j] = i; |
448 | } | 467 | } |
449 | for (i = 0; i < num_nodes; i++) | 468 | for (i = 0; i < num_nodes; i++) |
@@ -454,7 +473,6 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) | |||
454 | for (i = 0; i < num_nodes; i++) | 473 | for (i = 0; i < num_nodes; i++) |
455 | if (fake_nodes[i].start != fake_nodes[i].end) | 474 | if (fake_nodes[i].start != fake_nodes[i].end) |
456 | node_set(i, nodes_parsed); | 475 | node_set(i, nodes_parsed); |
457 | WARN_ON(!nodes_cover_memory(fake_nodes)); | ||
458 | } | 476 | } |
459 | 477 | ||
460 | static int null_slit_node_compare(int a, int b) | 478 | static int null_slit_node_compare(int a, int b) |