aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-01-23 08:37:40 -0500
committerIngo Molnar <mingo@elte.hu>2011-01-28 08:54:09 -0500
commit645a79195f66eb68ef3ab2b21d9829ac3aa085a9 (patch)
tree5808c94ad0371f70a391e1e77baf12465969e19c /arch/x86
parentbbc9e2f452d9c4b166d1f9a78d941d80173312fe (diff)
x86: Unify CPU -> NUMA node mapping between 32 and 64bit
Unlike 64bit, 32bit has been using its own cpu_to_node_map[] for CPU -> NUMA node mapping. Replace it with early_percpu variable x86_cpu_to_node_map and share the mapping code with 64bit. * USE_PERCPU_NUMA_NODE_ID is now enabled for 32bit too. * x86_cpu_to_node_map and numa_set/clear_node() are moved from numa_64 to numa. For now, on 32bit, x86_cpu_to_node_map is initialized with 0 instead of NUMA_NO_NODE. This is to avoid introducing unexpected behavior change and will be updated once init path is unified. * srat_detect_node() is now enabled for x86_32 too. It calls numa_set_node() and initializes the mapping making explicit cpu_to_node_map[] updates from map/unmap_cpu_to_node() unnecessary. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: eric.dumazet@gmail.com Cc: yinghai@kernel.org Cc: brgerst@gmail.com Cc: gorcunov@gmail.com Cc: penberg@kernel.org Cc: shaohui.zheng@intel.com Cc: rientjes@google.com LKML-Reference: <1295789862-25482-15-git-send-email-tj@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: David Rientjes <rientjes@google.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/numa.h8
-rw-r--r--arch/x86/include/asm/numa_64.h4
-rw-r--r--arch/x86/include/asm/topology.h17
-rw-r--r--arch/x86/kernel/acpi/boot.c5
-rw-r--r--arch/x86/kernel/cpu/amd.c4
-rw-r--r--arch/x86/kernel/cpu/intel.c2
-rw-r--r--arch/x86/kernel/setup_percpu.c4
-rw-r--r--arch/x86/kernel/smpboot.c6
-rw-r--r--arch/x86/mm/numa.c72
-rw-r--r--arch/x86/mm/numa_64.c65
11 files changed, 85 insertions, 104 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d5ed94d30aad..95c36c474766 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1705,7 +1705,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
1705 depends on NUMA 1705 depends on NUMA
1706 1706
1707config USE_PERCPU_NUMA_NODE_ID 1707config USE_PERCPU_NUMA_NODE_ID
1708 def_bool X86_64 1708 def_bool y
1709 depends on NUMA 1709 depends on NUMA
1710 1710
1711menu "Power management and ACPI options" 1711menu "Power management and ACPI options"
diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h
index 5e01c768a575..2b21fff9f655 100644
--- a/arch/x86/include/asm/numa.h
+++ b/arch/x86/include/asm/numa.h
@@ -30,4 +30,12 @@ static inline void set_apicid_to_node(int apicid, s16 node)
30# include "numa_64.h" 30# include "numa_64.h"
31#endif 31#endif
32 32
33#ifdef CONFIG_NUMA
34extern void __cpuinit numa_set_node(int cpu, int node);
35extern void __cpuinit numa_clear_node(int cpu);
36#else /* CONFIG_NUMA */
37static inline void numa_set_node(int cpu, int node) { }
38static inline void numa_clear_node(int cpu) { }
39#endif /* CONFIG_NUMA */
40
33#endif /* _ASM_X86_NUMA_H */ 41#endif /* _ASM_X86_NUMA_H */
diff --git a/arch/x86/include/asm/numa_64.h b/arch/x86/include/asm/numa_64.h
index 4982a9c08c2f..6ead9f361bda 100644
--- a/arch/x86/include/asm/numa_64.h
+++ b/arch/x86/include/asm/numa_64.h
@@ -30,8 +30,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start,
30 30
31extern void __init init_cpu_to_node(void); 31extern void __init init_cpu_to_node(void);
32extern int __cpuinit numa_cpu_node(int cpu); 32extern int __cpuinit numa_cpu_node(int cpu);
33extern void __cpuinit numa_set_node(int cpu, int node);
34extern void __cpuinit numa_clear_node(int cpu);
35extern void __cpuinit numa_add_cpu(int cpu); 33extern void __cpuinit numa_add_cpu(int cpu);
36extern void __cpuinit numa_remove_cpu(int cpu); 34extern void __cpuinit numa_remove_cpu(int cpu);
37 35
@@ -43,8 +41,6 @@ void numa_emu_cmdline(char *);
43#else 41#else
44static inline void init_cpu_to_node(void) { } 42static inline void init_cpu_to_node(void) { }
45static inline int numa_cpu_node(int cpu) { return NUMA_NO_NODE; } 43static inline int numa_cpu_node(int cpu) { return NUMA_NO_NODE; }
46static inline void numa_set_node(int cpu, int node) { }
47static inline void numa_clear_node(int cpu) { }
48static inline void numa_add_cpu(int cpu, int node) { } 44static inline void numa_add_cpu(int cpu, int node) { }
49static inline void numa_remove_cpu(int cpu) { } 45static inline void numa_remove_cpu(int cpu) { }
50#endif 46#endif
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 21899cc31e52..b101c17861f5 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -47,21 +47,6 @@
47 47
48#include <asm/mpspec.h> 48#include <asm/mpspec.h>
49 49
50#ifdef CONFIG_X86_32
51
52/* Mappings between logical cpu number and node number */
53extern int cpu_to_node_map[];
54
55/* Returns the number of the node containing CPU 'cpu' */
56static inline int __cpu_to_node(int cpu)
57{
58 return cpu_to_node_map[cpu];
59}
60#define early_cpu_to_node __cpu_to_node
61#define cpu_to_node __cpu_to_node
62
63#else /* CONFIG_X86_64 */
64
65/* Mappings between logical cpu number and node number */ 50/* Mappings between logical cpu number and node number */
66DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map); 51DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
67 52
@@ -84,8 +69,6 @@ static inline int early_cpu_to_node(int cpu)
84 69
85#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ 70#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
86 71
87#endif /* CONFIG_X86_64 */
88
89/* Mappings between node number and cpus on that node. */ 72/* Mappings between node number and cpus on that node. */
90extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES]; 73extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
91 74
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a7bca59ec595..a2c512175395 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -590,12 +590,7 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)
590 if (nid == -1 || !node_online(nid)) 590 if (nid == -1 || !node_online(nid))
591 return; 591 return;
592 set_apicid_to_node(physid, nid); 592 set_apicid_to_node(physid, nid);
593#ifdef CONFIG_X86_64
594 numa_set_node(cpu, nid); 593 numa_set_node(cpu, nid);
595#else /* CONFIG_X86_32 */
596 cpu_to_node_map[cpu] = nid;
597#endif
598
599#endif 594#endif
600} 595}
601 596
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 3cce8f2bb2e1..77858fd64620 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -233,7 +233,7 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
233} 233}
234#endif 234#endif
235 235
236#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 236#ifdef CONFIG_NUMA
237/* 237/*
238 * To workaround broken NUMA config. Read the comment in 238 * To workaround broken NUMA config. Read the comment in
239 * srat_detect_node(). 239 * srat_detect_node().
@@ -338,7 +338,7 @@ EXPORT_SYMBOL_GPL(amd_get_nb_id);
338 338
339static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) 339static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
340{ 340{
341#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 341#ifdef CONFIG_NUMA
342 int cpu = smp_processor_id(); 342 int cpu = smp_processor_id();
343 int node; 343 int node;
344 unsigned apicid = c->apicid; 344 unsigned apicid = c->apicid;
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 6052004bf4f4..df86bc8c859d 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -276,7 +276,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
276 276
277static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) 277static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
278{ 278{
279#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) 279#ifdef CONFIG_NUMA
280 unsigned node; 280 unsigned node;
281 int cpu = smp_processor_id(); 281 int cpu = smp_processor_id();
282 282
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index b5147f00f0ef..71f4727da373 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -233,6 +233,7 @@ void __init setup_per_cpu_areas(void)
233 per_cpu(irq_stack_ptr, cpu) = 233 per_cpu(irq_stack_ptr, cpu) =
234 per_cpu(irq_stack_union.irq_stack, cpu) + 234 per_cpu(irq_stack_union.irq_stack, cpu) +
235 IRQ_STACK_SIZE - 64; 235 IRQ_STACK_SIZE - 64;
236#endif
236#ifdef CONFIG_NUMA 237#ifdef CONFIG_NUMA
237 per_cpu(x86_cpu_to_node_map, cpu) = 238 per_cpu(x86_cpu_to_node_map, cpu) =
238 early_per_cpu_map(x86_cpu_to_node_map, cpu); 239 early_per_cpu_map(x86_cpu_to_node_map, cpu);
@@ -246,7 +247,6 @@ void __init setup_per_cpu_areas(void)
246 */ 247 */
247 set_cpu_numa_node(cpu, early_cpu_to_node(cpu)); 248 set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
248#endif 249#endif
249#endif
250 /* 250 /*
251 * Up to this point, the boot CPU has been using .init.data 251 * Up to this point, the boot CPU has been using .init.data
252 * area. Reload any changed state for the boot CPU. 252 * area. Reload any changed state for the boot CPU.
@@ -263,7 +263,7 @@ void __init setup_per_cpu_areas(void)
263#ifdef CONFIG_X86_32 263#ifdef CONFIG_X86_32
264 early_per_cpu_ptr(x86_cpu_to_logical_apicid) = NULL; 264 early_per_cpu_ptr(x86_cpu_to_logical_apicid) = NULL;
265#endif 265#endif
266#if defined(CONFIG_X86_64) && defined(CONFIG_NUMA) 266#ifdef CONFIG_NUMA
267 early_per_cpu_ptr(x86_cpu_to_node_map) = NULL; 267 early_per_cpu_ptr(x86_cpu_to_node_map) = NULL;
268#endif 268#endif
269 269
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index b7cfce535cb0..2c203822424f 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -133,16 +133,11 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
133atomic_t init_deasserted; 133atomic_t init_deasserted;
134 134
135#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) 135#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
136/* which node each logical CPU is on */
137int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
138EXPORT_SYMBOL(cpu_to_node_map);
139
140/* set up a mapping between cpu and node. */ 136/* set up a mapping between cpu and node. */
141static void map_cpu_to_node(int cpu, int node) 137static void map_cpu_to_node(int cpu, int node)
142{ 138{
143 printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node); 139 printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
144 cpumask_set_cpu(cpu, node_to_cpumask_map[node]); 140 cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
145 cpu_to_node_map[cpu] = node;
146} 141}
147 142
148/* undo a mapping between cpu and node. */ 143/* undo a mapping between cpu and node. */
@@ -153,7 +148,6 @@ static void unmap_cpu_to_node(int cpu)
153 printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu); 148 printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
154 for (node = 0; node < MAX_NUMNODES; node++) 149 for (node = 0; node < MAX_NUMNODES; node++)
155 cpumask_clear_cpu(cpu, node_to_cpumask_map[node]); 150 cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
156 cpu_to_node_map[cpu] = 0;
157} 151}
158#else /* !(CONFIG_NUMA && CONFIG_X86_32) */ 152#else /* !(CONFIG_NUMA && CONFIG_X86_32) */
159#define map_cpu_to_node(cpu, node) ({}) 153#define map_cpu_to_node(cpu, node) ({})
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 480b3571c8b1..187810be3d6c 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -36,6 +36,44 @@ cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
36EXPORT_SYMBOL(node_to_cpumask_map); 36EXPORT_SYMBOL(node_to_cpumask_map);
37 37
38/* 38/*
39 * Map cpu index to node index
40 */
41#ifdef CONFIG_X86_32
42DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, 0);
43#else
44DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
45#endif
46EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
47
48void __cpuinit numa_set_node(int cpu, int node)
49{
50 int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
51
52 /* early setting, no percpu area yet */
53 if (cpu_to_node_map) {
54 cpu_to_node_map[cpu] = node;
55 return;
56 }
57
58#ifdef CONFIG_DEBUG_PER_CPU_MAPS
59 if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) {
60 printk(KERN_ERR "numa_set_node: invalid cpu# (%d)\n", cpu);
61 dump_stack();
62 return;
63 }
64#endif
65 per_cpu(x86_cpu_to_node_map, cpu) = node;
66
67 if (node != NUMA_NO_NODE)
68 set_cpu_numa_node(cpu, node);
69}
70
71void __cpuinit numa_clear_node(int cpu)
72{
73 numa_set_node(cpu, NUMA_NO_NODE);
74}
75
76/*
39 * Allocate node_to_cpumask_map based on number of available nodes 77 * Allocate node_to_cpumask_map based on number of available nodes
40 * Requires node_possible_map to be valid. 78 * Requires node_possible_map to be valid.
41 * 79 *
@@ -62,6 +100,37 @@ void __init setup_node_to_cpumask_map(void)
62} 100}
63 101
64#ifdef CONFIG_DEBUG_PER_CPU_MAPS 102#ifdef CONFIG_DEBUG_PER_CPU_MAPS
103
104int __cpu_to_node(int cpu)
105{
106 if (early_per_cpu_ptr(x86_cpu_to_node_map)) {
107 printk(KERN_WARNING
108 "cpu_to_node(%d): usage too early!\n", cpu);
109 dump_stack();
110 return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
111 }
112 return per_cpu(x86_cpu_to_node_map, cpu);
113}
114EXPORT_SYMBOL(__cpu_to_node);
115
116/*
117 * Same function as cpu_to_node() but used if called before the
118 * per_cpu areas are setup.
119 */
120int early_cpu_to_node(int cpu)
121{
122 if (early_per_cpu_ptr(x86_cpu_to_node_map))
123 return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
124
125 if (!cpu_possible(cpu)) {
126 printk(KERN_WARNING
127 "early_cpu_to_node(%d): no per_cpu area!\n", cpu);
128 dump_stack();
129 return NUMA_NO_NODE;
130 }
131 return per_cpu(x86_cpu_to_node_map, cpu);
132}
133
65/* 134/*
66 * Returns a pointer to the bitmask of CPUs on Node 'node'. 135 * Returns a pointer to the bitmask of CPUs on Node 'node'.
67 */ 136 */
@@ -84,4 +153,5 @@ const struct cpumask *cpumask_of_node(int node)
84 return node_to_cpumask_map[node]; 153 return node_to_cpumask_map[node];
85} 154}
86EXPORT_SYMBOL(cpumask_of_node); 155EXPORT_SYMBOL(cpumask_of_node);
87#endif 156
157#endif /* CONFIG_DEBUG_PER_CPU_MAPS */
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 1e1026f61a5a..f5459400644d 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -30,12 +30,6 @@ static unsigned long __initdata nodemap_addr;
30static unsigned long __initdata nodemap_size; 30static unsigned long __initdata nodemap_size;
31 31
32/* 32/*
33 * Map cpu index to node index
34 */
35DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
36EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
37
38/*
39 * Given a shift value, try to populate memnodemap[] 33 * Given a shift value, try to populate memnodemap[]
40 * Returns : 34 * Returns :
41 * 1 if OK 35 * 1 if OK
@@ -732,34 +726,6 @@ int __cpuinit numa_cpu_node(int cpu)
732 return NUMA_NO_NODE; 726 return NUMA_NO_NODE;
733} 727}
734 728
735void __cpuinit numa_set_node(int cpu, int node)
736{
737 int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
738
739 /* early setting, no percpu area yet */
740 if (cpu_to_node_map) {
741 cpu_to_node_map[cpu] = node;
742 return;
743 }
744
745#ifdef CONFIG_DEBUG_PER_CPU_MAPS
746 if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) {
747 printk(KERN_ERR "numa_set_node: invalid cpu# (%d)\n", cpu);
748 dump_stack();
749 return;
750 }
751#endif
752 per_cpu(x86_cpu_to_node_map, cpu) = node;
753
754 if (node != NUMA_NO_NODE)
755 set_cpu_numa_node(cpu, node);
756}
757
758void __cpuinit numa_clear_node(int cpu)
759{
760 numa_set_node(cpu, NUMA_NO_NODE);
761}
762
763#ifndef CONFIG_DEBUG_PER_CPU_MAPS 729#ifndef CONFIG_DEBUG_PER_CPU_MAPS
764 730
765#ifndef CONFIG_NUMA_EMU 731#ifndef CONFIG_NUMA_EMU
@@ -887,37 +853,6 @@ void __cpuinit numa_remove_cpu(int cpu)
887{ 853{
888 numa_set_cpumask(cpu, 0); 854 numa_set_cpumask(cpu, 0);
889} 855}
890
891int __cpu_to_node(int cpu)
892{
893 if (early_per_cpu_ptr(x86_cpu_to_node_map)) {
894 printk(KERN_WARNING
895 "cpu_to_node(%d): usage too early!\n", cpu);
896 dump_stack();
897 return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
898 }
899 return per_cpu(x86_cpu_to_node_map, cpu);
900}
901EXPORT_SYMBOL(__cpu_to_node);
902
903/*
904 * Same function as cpu_to_node() but used if called before the
905 * per_cpu areas are setup.
906 */
907int early_cpu_to_node(int cpu)
908{
909 if (early_per_cpu_ptr(x86_cpu_to_node_map))
910 return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
911
912 if (!cpu_possible(cpu)) {
913 printk(KERN_WARNING
914 "early_cpu_to_node(%d): no per_cpu area!\n", cpu);
915 dump_stack();
916 return NUMA_NO_NODE;
917 }
918 return per_cpu(x86_cpu_to_node_map, cpu);
919}
920
921/* 856/*
922 * --------- end of debug versions of the numa functions --------- 857 * --------- end of debug versions of the numa functions ---------
923 */ 858 */