aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2011-01-10 03:35:57 -0500
committerIngo Molnar <mingo@elte.hu>2011-01-10 03:36:07 -0500
commit9adcc4a127be6c979eae1ae34083261f2ec5dfec (patch)
tree93652985f5dc4c0e38fda60dd03fca2583932094
parent30285c6f03be05f6f894b50d03bcb638886e3936 (diff)
parentd906f0eb2f0e6d1a24c479f69a9c39e7e45c5ae8 (diff)
Merge branch 'x86/numa' into x86/urgent
Merge reason: Topic is ready for upstream. Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/include/asm/acpi.h11
-rw-r--r--arch/x86/include/asm/amd_nb.h6
-rw-r--r--arch/x86/include/asm/numa_64.h2
-rw-r--r--arch/x86/mm/amdtopology_64.c86
-rw-r--r--arch/x86/mm/numa_64.c157
-rw-r--r--arch/x86/mm/srat_64.c26
6 files changed, 225 insertions, 63 deletions
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 55d106b5e31b..211ca3f7fd16 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -185,17 +185,16 @@ struct bootnode;
185 185
186#ifdef CONFIG_ACPI_NUMA 186#ifdef CONFIG_ACPI_NUMA
187extern int acpi_numa; 187extern int acpi_numa;
188extern int acpi_get_nodes(struct bootnode *physnodes); 188extern void acpi_get_nodes(struct bootnode *physnodes, unsigned long start,
189 unsigned long end);
189extern int acpi_scan_nodes(unsigned long start, unsigned long end); 190extern int acpi_scan_nodes(unsigned long start, unsigned long end);
190#define NR_NODE_MEMBLKS (MAX_NUMNODES*2) 191#define NR_NODE_MEMBLKS (MAX_NUMNODES*2)
192
193#ifdef CONFIG_NUMA_EMU
191extern void acpi_fake_nodes(const struct bootnode *fake_nodes, 194extern void acpi_fake_nodes(const struct bootnode *fake_nodes,
192 int num_nodes); 195 int num_nodes);
193#else
194static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
195 int num_nodes)
196{
197}
198#endif 196#endif
197#endif /* CONFIG_ACPI_NUMA */
199 198
200#define acpi_unlazy_tlb(x) leave_mm(x) 199#define acpi_unlazy_tlb(x) leave_mm(x)
201 200
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index 6aee50d655d1..980f22567631 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -9,10 +9,14 @@ struct bootnode;
9extern int early_is_amd_nb(u32 value); 9extern int early_is_amd_nb(u32 value);
10extern int amd_cache_northbridges(void); 10extern int amd_cache_northbridges(void);
11extern void amd_flush_garts(void); 11extern void amd_flush_garts(void);
12extern int amd_get_nodes(struct bootnode *nodes);
13extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn); 12extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn);
14extern int amd_scan_nodes(void); 13extern int amd_scan_nodes(void);
15 14
15#ifdef CONFIG_NUMA_EMU
16extern void amd_fake_nodes(const struct bootnode *nodes, int nr_nodes);
17extern void amd_get_nodes(struct bootnode *nodes);
18#endif
19
16struct amd_northbridge { 20struct amd_northbridge {
17 struct pci_dev *misc; 21 struct pci_dev *misc;
18}; 22};
diff --git a/arch/x86/include/asm/numa_64.h b/arch/x86/include/asm/numa_64.h
index 823e070e7c26..5ae87285a502 100644
--- a/arch/x86/include/asm/numa_64.h
+++ b/arch/x86/include/asm/numa_64.h
@@ -38,7 +38,7 @@ extern void __cpuinit numa_add_cpu(int cpu);
38extern void __cpuinit numa_remove_cpu(int cpu); 38extern void __cpuinit numa_remove_cpu(int cpu);
39 39
40#ifdef CONFIG_NUMA_EMU 40#ifdef CONFIG_NUMA_EMU
41#define FAKE_NODE_MIN_SIZE ((u64)64 << 20) 41#define FAKE_NODE_MIN_SIZE ((u64)32 << 20)
42#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) 42#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))
43#endif /* CONFIG_NUMA_EMU */ 43#endif /* CONFIG_NUMA_EMU */
44#else 44#else
diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c
index 08a0069b87a5..f21962c435ed 100644
--- a/arch/x86/mm/amdtopology_64.c
+++ b/arch/x86/mm/amdtopology_64.c
@@ -27,6 +27,7 @@
27#include <asm/amd_nb.h> 27#include <asm/amd_nb.h>
28 28
29static struct bootnode __initdata nodes[8]; 29static struct bootnode __initdata nodes[8];
30static unsigned char __initdata nodeids[8];
30static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE; 31static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE;
31 32
32static __init int find_northbridge(void) 33static __init int find_northbridge(void)
@@ -68,19 +69,6 @@ static __init void early_get_boot_cpu_id(void)
68#endif 69#endif
69} 70}
70 71
71int __init amd_get_nodes(struct bootnode *physnodes)
72{
73 int i;
74 int ret = 0;
75
76 for_each_node_mask(i, nodes_parsed) {
77 physnodes[ret].start = nodes[i].start;
78 physnodes[ret].end = nodes[i].end;
79 ret++;
80 }
81 return ret;
82}
83
84int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) 72int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
85{ 73{
86 unsigned long start = PFN_PHYS(start_pfn); 74 unsigned long start = PFN_PHYS(start_pfn);
@@ -113,7 +101,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
113 base = read_pci_config(0, nb, 1, 0x40 + i*8); 101 base = read_pci_config(0, nb, 1, 0x40 + i*8);
114 limit = read_pci_config(0, nb, 1, 0x44 + i*8); 102 limit = read_pci_config(0, nb, 1, 0x44 + i*8);
115 103
116 nodeid = limit & 7; 104 nodeids[i] = nodeid = limit & 7;
117 if ((base & 3) == 0) { 105 if ((base & 3) == 0) {
118 if (i < numnodes) 106 if (i < numnodes)
119 pr_info("Skipping disabled node %d\n", i); 107 pr_info("Skipping disabled node %d\n", i);
@@ -193,6 +181,76 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn)
193 return 0; 181 return 0;
194} 182}
195 183
184#ifdef CONFIG_NUMA_EMU
185static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = {
186 [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
187};
188
189void __init amd_get_nodes(struct bootnode *physnodes)
190{
191 int i;
192
193 for_each_node_mask(i, nodes_parsed) {
194 physnodes[i].start = nodes[i].start;
195 physnodes[i].end = nodes[i].end;
196 }
197}
198
199static int __init find_node_by_addr(unsigned long addr)
200{
201 int ret = NUMA_NO_NODE;
202 int i;
203
204 for (i = 0; i < 8; i++)
205 if (addr >= nodes[i].start && addr < nodes[i].end) {
206 ret = i;
207 break;
208 }
209 return ret;
210}
211
212/*
213 * For NUMA emulation, fake proximity domain (_PXM) to node id mappings must be
214 * setup to represent the physical topology but reflect the emulated
215 * environment. For each emulated node, the real node which it appears on is
216 * found and a fake pxm to nid mapping is created which mirrors the actual
217 * locality. node_distance() then represents the correct distances between
218 * emulated nodes by using the fake acpi mappings to pxms.
219 */
220void __init amd_fake_nodes(const struct bootnode *nodes, int nr_nodes)
221{
222 unsigned int bits;
223 unsigned int cores;
224 unsigned int apicid_base = 0;
225 int i;
226
227 bits = boot_cpu_data.x86_coreid_bits;
228 cores = 1 << bits;
229 early_get_boot_cpu_id();
230 if (boot_cpu_physical_apicid > 0)
231 apicid_base = boot_cpu_physical_apicid;
232
233 for (i = 0; i < nr_nodes; i++) {
234 int index;
235 int nid;
236 int j;
237
238 nid = find_node_by_addr(nodes[i].start);
239 if (nid == NUMA_NO_NODE)
240 continue;
241
242 index = nodeids[nid] << bits;
243 if (fake_apicid_to_node[index + apicid_base] == NUMA_NO_NODE)
244 for (j = apicid_base; j < cores + apicid_base; j++)
245 fake_apicid_to_node[index + j] = i;
246#ifdef CONFIG_ACPI_NUMA
247 __acpi_map_pxm_to_node(nid, i);
248#endif
249 }
250 memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));
251}
252#endif /* CONFIG_NUMA_EMU */
253
196int __init amd_scan_nodes(void) 254int __init amd_scan_nodes(void)
197{ 255{
198 unsigned int bits; 256 unsigned int bits;
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 7762a517d69d..1e72102e80c9 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -260,30 +260,30 @@ void __init numa_init_array(void)
260#ifdef CONFIG_NUMA_EMU 260#ifdef CONFIG_NUMA_EMU
261/* Numa emulation */ 261/* Numa emulation */
262static struct bootnode nodes[MAX_NUMNODES] __initdata; 262static struct bootnode nodes[MAX_NUMNODES] __initdata;
263static struct bootnode physnodes[MAX_NUMNODES] __initdata; 263static struct bootnode physnodes[MAX_NUMNODES] __cpuinitdata;
264static char *cmdline __initdata; 264static char *cmdline __initdata;
265 265
266static int __init setup_physnodes(unsigned long start, unsigned long end, 266static int __init setup_physnodes(unsigned long start, unsigned long end,
267 int acpi, int amd) 267 int acpi, int amd)
268{ 268{
269 int nr_nodes = 0;
270 int ret = 0; 269 int ret = 0;
271 int i; 270 int i;
272 271
272 memset(physnodes, 0, sizeof(physnodes));
273#ifdef CONFIG_ACPI_NUMA 273#ifdef CONFIG_ACPI_NUMA
274 if (acpi) 274 if (acpi)
275 nr_nodes = acpi_get_nodes(physnodes); 275 acpi_get_nodes(physnodes, start, end);
276#endif 276#endif
277#ifdef CONFIG_AMD_NUMA 277#ifdef CONFIG_AMD_NUMA
278 if (amd) 278 if (amd)
279 nr_nodes = amd_get_nodes(physnodes); 279 amd_get_nodes(physnodes);
280#endif 280#endif
281 /* 281 /*
282 * Basic sanity checking on the physical node map: there may be errors 282 * Basic sanity checking on the physical node map: there may be errors
283 * if the SRAT or AMD code incorrectly reported the topology or the mem= 283 * if the SRAT or AMD code incorrectly reported the topology or the mem=
284 * kernel parameter is used. 284 * kernel parameter is used.
285 */ 285 */
286 for (i = 0; i < nr_nodes; i++) { 286 for (i = 0; i < MAX_NUMNODES; i++) {
287 if (physnodes[i].start == physnodes[i].end) 287 if (physnodes[i].start == physnodes[i].end)
288 continue; 288 continue;
289 if (physnodes[i].start > end) { 289 if (physnodes[i].start > end) {
@@ -298,17 +298,6 @@ static int __init setup_physnodes(unsigned long start, unsigned long end,
298 physnodes[i].start = start; 298 physnodes[i].start = start;
299 if (physnodes[i].end > end) 299 if (physnodes[i].end > end)
300 physnodes[i].end = end; 300 physnodes[i].end = end;
301 }
302
303 /*
304 * Remove all nodes that have no memory or were truncated because of the
305 * limited address range.
306 */
307 for (i = 0; i < nr_nodes; i++) {
308 if (physnodes[i].start == physnodes[i].end)
309 continue;
310 physnodes[ret].start = physnodes[i].start;
311 physnodes[ret].end = physnodes[i].end;
312 ret++; 301 ret++;
313 } 302 }
314 303
@@ -324,6 +313,24 @@ static int __init setup_physnodes(unsigned long start, unsigned long end,
324 return ret; 313 return ret;
325} 314}
326 315
316static void __init fake_physnodes(int acpi, int amd, int nr_nodes)
317{
318 int i;
319
320 BUG_ON(acpi && amd);
321#ifdef CONFIG_ACPI_NUMA
322 if (acpi)
323 acpi_fake_nodes(nodes, nr_nodes);
324#endif
325#ifdef CONFIG_AMD_NUMA
326 if (amd)
327 amd_fake_nodes(nodes, nr_nodes);
328#endif
329 if (!acpi && !amd)
330 for (i = 0; i < nr_cpu_ids; i++)
331 numa_set_node(i, 0);
332}
333
327/* 334/*
328 * Setups up nid to range from addr to addr + size. If the end 335 * Setups up nid to range from addr to addr + size. If the end
329 * boundary is greater than max_addr, then max_addr is used instead. 336 * boundary is greater than max_addr, then max_addr is used instead.
@@ -352,8 +359,7 @@ static int __init setup_node_range(int nid, u64 *addr, u64 size, u64 max_addr)
352 * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr 359 * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr
353 * to max_addr. The return value is the number of nodes allocated. 360 * to max_addr. The return value is the number of nodes allocated.
354 */ 361 */
355static int __init split_nodes_interleave(u64 addr, u64 max_addr, 362static int __init split_nodes_interleave(u64 addr, u64 max_addr, int nr_nodes)
356 int nr_phys_nodes, int nr_nodes)
357{ 363{
358 nodemask_t physnode_mask = NODE_MASK_NONE; 364 nodemask_t physnode_mask = NODE_MASK_NONE;
359 u64 size; 365 u64 size;
@@ -384,7 +390,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr,
384 return -1; 390 return -1;
385 } 391 }
386 392
387 for (i = 0; i < nr_phys_nodes; i++) 393 for (i = 0; i < MAX_NUMNODES; i++)
388 if (physnodes[i].start != physnodes[i].end) 394 if (physnodes[i].start != physnodes[i].end)
389 node_set(i, physnode_mask); 395 node_set(i, physnode_mask);
390 396
@@ -553,11 +559,9 @@ static int __init numa_emulation(unsigned long start_pfn,
553{ 559{
554 u64 addr = start_pfn << PAGE_SHIFT; 560 u64 addr = start_pfn << PAGE_SHIFT;
555 u64 max_addr = last_pfn << PAGE_SHIFT; 561 u64 max_addr = last_pfn << PAGE_SHIFT;
556 int num_phys_nodes;
557 int num_nodes; 562 int num_nodes;
558 int i; 563 int i;
559 564
560 num_phys_nodes = setup_physnodes(addr, max_addr, acpi, amd);
561 /* 565 /*
562 * If the numa=fake command-line contains a 'M' or 'G', it represents 566 * If the numa=fake command-line contains a 'M' or 'G', it represents
563 * the fixed node size. Otherwise, if it is just a single number N, 567 * the fixed node size. Otherwise, if it is just a single number N,
@@ -572,7 +576,7 @@ static int __init numa_emulation(unsigned long start_pfn,
572 unsigned long n; 576 unsigned long n;
573 577
574 n = simple_strtoul(cmdline, NULL, 0); 578 n = simple_strtoul(cmdline, NULL, 0);
575 num_nodes = split_nodes_interleave(addr, max_addr, num_phys_nodes, n); 579 num_nodes = split_nodes_interleave(addr, max_addr, n);
576 } 580 }
577 581
578 if (num_nodes < 0) 582 if (num_nodes < 0)
@@ -595,7 +599,8 @@ static int __init numa_emulation(unsigned long start_pfn,
595 nodes[i].end >> PAGE_SHIFT); 599 nodes[i].end >> PAGE_SHIFT);
596 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 600 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
597 } 601 }
598 acpi_fake_nodes(nodes, num_nodes); 602 setup_physnodes(addr, max_addr, acpi, amd);
603 fake_physnodes(acpi, amd, num_nodes);
599 numa_init_array(); 604 numa_init_array();
600 return 0; 605 return 0;
601} 606}
@@ -610,8 +615,12 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn,
610 nodes_clear(node_online_map); 615 nodes_clear(node_online_map);
611 616
612#ifdef CONFIG_NUMA_EMU 617#ifdef CONFIG_NUMA_EMU
618 setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT,
619 acpi, amd);
613 if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, amd)) 620 if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, amd))
614 return; 621 return;
622 setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT,
623 acpi, amd);
615 nodes_clear(node_possible_map); 624 nodes_clear(node_possible_map);
616 nodes_clear(node_online_map); 625 nodes_clear(node_online_map);
617#endif 626#endif
@@ -767,6 +776,7 @@ void __cpuinit numa_clear_node(int cpu)
767 776
768#ifndef CONFIG_DEBUG_PER_CPU_MAPS 777#ifndef CONFIG_DEBUG_PER_CPU_MAPS
769 778
779#ifndef CONFIG_NUMA_EMU
770void __cpuinit numa_add_cpu(int cpu) 780void __cpuinit numa_add_cpu(int cpu)
771{ 781{
772 cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); 782 cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
@@ -776,34 +786,115 @@ void __cpuinit numa_remove_cpu(int cpu)
776{ 786{
777 cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); 787 cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
778} 788}
789#else
790void __cpuinit numa_add_cpu(int cpu)
791{
792 unsigned long addr;
793 u16 apicid;
794 int physnid;
795 int nid = NUMA_NO_NODE;
796
797 apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
798 if (apicid != BAD_APICID)
799 nid = apicid_to_node[apicid];
800 if (nid == NUMA_NO_NODE)
801 nid = early_cpu_to_node(cpu);
802 BUG_ON(nid == NUMA_NO_NODE || !node_online(nid));
803
804 /*
805 * Use the starting address of the emulated node to find which physical
806 * node it is allocated on.
807 */
808 addr = node_start_pfn(nid) << PAGE_SHIFT;
809 for (physnid = 0; physnid < MAX_NUMNODES; physnid++)
810 if (addr >= physnodes[physnid].start &&
811 addr < physnodes[physnid].end)
812 break;
813
814 /*
815 * Map the cpu to each emulated node that is allocated on the physical
816 * node of the cpu's apic id.
817 */
818 for_each_online_node(nid) {
819 addr = node_start_pfn(nid) << PAGE_SHIFT;
820 if (addr >= physnodes[physnid].start &&
821 addr < physnodes[physnid].end)
822 cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
823 }
824}
825
826void __cpuinit numa_remove_cpu(int cpu)
827{
828 int i;
829
830 for_each_online_node(i)
831 cpumask_clear_cpu(cpu, node_to_cpumask_map[i]);
832}
833#endif /* !CONFIG_NUMA_EMU */
779 834
780#else /* CONFIG_DEBUG_PER_CPU_MAPS */ 835#else /* CONFIG_DEBUG_PER_CPU_MAPS */
836static struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable)
837{
838 int node = early_cpu_to_node(cpu);
839 struct cpumask *mask;
840 char buf[64];
841
842 mask = node_to_cpumask_map[node];
843 if (!mask) {
844 pr_err("node_to_cpumask_map[%i] NULL\n", node);
845 dump_stack();
846 return NULL;
847 }
848
849 cpulist_scnprintf(buf, sizeof(buf), mask);
850 printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
851 enable ? "numa_add_cpu" : "numa_remove_cpu",
852 cpu, node, buf);
853 return mask;
854}
781 855
782/* 856/*
783 * --------- debug versions of the numa functions --------- 857 * --------- debug versions of the numa functions ---------
784 */ 858 */
859#ifndef CONFIG_NUMA_EMU
785static void __cpuinit numa_set_cpumask(int cpu, int enable) 860static void __cpuinit numa_set_cpumask(int cpu, int enable)
786{ 861{
787 int node = early_cpu_to_node(cpu);
788 struct cpumask *mask; 862 struct cpumask *mask;
789 char buf[64];
790 863
791 mask = node_to_cpumask_map[node]; 864 mask = debug_cpumask_set_cpu(cpu, enable);
792 if (mask == NULL) { 865 if (!mask)
793 printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
794 dump_stack();
795 return; 866 return;
796 }
797 867
798 if (enable) 868 if (enable)
799 cpumask_set_cpu(cpu, mask); 869 cpumask_set_cpu(cpu, mask);
800 else 870 else
801 cpumask_clear_cpu(cpu, mask); 871 cpumask_clear_cpu(cpu, mask);
872}
873#else
874static void __cpuinit numa_set_cpumask(int cpu, int enable)
875{
876 int node = early_cpu_to_node(cpu);
877 struct cpumask *mask;
878 int i;
802 879
803 cpulist_scnprintf(buf, sizeof(buf), mask); 880 for_each_online_node(i) {
804 printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n", 881 unsigned long addr;
805 enable ? "numa_add_cpu" : "numa_remove_cpu", cpu, node, buf); 882
883 addr = node_start_pfn(i) << PAGE_SHIFT;
884 if (addr < physnodes[node].start ||
885 addr >= physnodes[node].end)
886 continue;
887 mask = debug_cpumask_set_cpu(cpu, enable);
888 if (!mask)
889 return;
890
891 if (enable)
892 cpumask_set_cpu(cpu, mask);
893 else
894 cpumask_clear_cpu(cpu, mask);
895 }
806} 896}
897#endif /* CONFIG_NUMA_EMU */
807 898
808void __cpuinit numa_add_cpu(int cpu) 899void __cpuinit numa_add_cpu(int cpu)
809{ 900{
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 171a0aacb99a..603d285d1daa 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -349,18 +349,19 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
349 349
350void __init acpi_numa_arch_fixup(void) {} 350void __init acpi_numa_arch_fixup(void) {}
351 351
352int __init acpi_get_nodes(struct bootnode *physnodes) 352#ifdef CONFIG_NUMA_EMU
353void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start,
354 unsigned long end)
353{ 355{
354 int i; 356 int i;
355 int ret = 0;
356 357
357 for_each_node_mask(i, nodes_parsed) { 358 for_each_node_mask(i, nodes_parsed) {
358 physnodes[ret].start = nodes[i].start; 359 cutoff_node(i, start, end);
359 physnodes[ret].end = nodes[i].end; 360 physnodes[i].start = nodes[i].start;
360 ret++; 361 physnodes[i].end = nodes[i].end;
361 } 362 }
362 return ret;
363} 363}
364#endif /* CONFIG_NUMA_EMU */
364 365
365/* Use the information discovered above to actually set up the nodes. */ 366/* Use the information discovered above to actually set up the nodes. */
366int __init acpi_scan_nodes(unsigned long start, unsigned long end) 367int __init acpi_scan_nodes(unsigned long start, unsigned long end)
@@ -505,8 +506,6 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
505{ 506{
506 int i, j; 507 int i, j;
507 508
508 printk(KERN_INFO "Faking PXM affinity for fake nodes on real "
509 "topology.\n");
510 for (i = 0; i < num_nodes; i++) { 509 for (i = 0; i < num_nodes; i++) {
511 int nid, pxm; 510 int nid, pxm;
512 511
@@ -526,6 +525,17 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
526 fake_apicid_to_node[j] == NUMA_NO_NODE) 525 fake_apicid_to_node[j] == NUMA_NO_NODE)
527 fake_apicid_to_node[j] = i; 526 fake_apicid_to_node[j] = i;
528 } 527 }
528
529 /*
530 * If there are apicid-to-node mappings for physical nodes that do not
531 * have a corresponding emulated node, it should default to a guaranteed
532 * value.
533 */
534 for (i = 0; i < MAX_LOCAL_APIC; i++)
535 if (apicid_to_node[i] != NUMA_NO_NODE &&
536 fake_apicid_to_node[i] == NUMA_NO_NODE)
537 fake_apicid_to_node[i] = 0;
538
529 for (i = 0; i < num_nodes; i++) 539 for (i = 0; i < num_nodes; i++)
530 __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i); 540 __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i);
531 memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node)); 541 memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));