aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/numa.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/numa.c')
-rw-r--r--arch/powerpc/mm/numa.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index eaa7633515b7..80d110635d24 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -33,16 +33,41 @@ static int numa_debug;
33#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } 33#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
34 34
35int numa_cpu_lookup_table[NR_CPUS]; 35int numa_cpu_lookup_table[NR_CPUS];
36cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; 36cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
37struct pglist_data *node_data[MAX_NUMNODES]; 37struct pglist_data *node_data[MAX_NUMNODES];
38 38
39EXPORT_SYMBOL(numa_cpu_lookup_table); 39EXPORT_SYMBOL(numa_cpu_lookup_table);
40EXPORT_SYMBOL(numa_cpumask_lookup_table); 40EXPORT_SYMBOL(node_to_cpumask_map);
41EXPORT_SYMBOL(node_data); 41EXPORT_SYMBOL(node_data);
42 42
43static int min_common_depth; 43static int min_common_depth;
44static int n_mem_addr_cells, n_mem_size_cells; 44static int n_mem_addr_cells, n_mem_size_cells;
45 45
46/*
47 * Allocate node_to_cpumask_map based on number of available nodes
48 * Requires node_possible_map to be valid.
49 *
50 * Note: node_to_cpumask() is not valid until after this is done.
51 */
52static void __init setup_node_to_cpumask_map(void)
53{
54 unsigned int node, num = 0;
55
56 /* setup nr_node_ids if not done yet */
57 if (nr_node_ids == MAX_NUMNODES) {
58 for_each_node_mask(node, node_possible_map)
59 num = node;
60 nr_node_ids = num + 1;
61 }
62
63 /* allocate the map */
64 for (node = 0; node < nr_node_ids; node++)
65 alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
66
67 /* cpumask_of_node() will now work */
68 dbg("Node to cpumask map for %d nodes\n", nr_node_ids);
69}
70
46static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, 71static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
47 unsigned int *nid) 72 unsigned int *nid)
48{ 73{
@@ -138,8 +163,8 @@ static void __cpuinit map_cpu_to_node(int cpu, int node)
138 163
139 dbg("adding cpu %d to node %d\n", cpu, node); 164 dbg("adding cpu %d to node %d\n", cpu, node);
140 165
141 if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node]))) 166 if (!(cpumask_test_cpu(cpu, node_to_cpumask_map[node])))
142 cpu_set(cpu, numa_cpumask_lookup_table[node]); 167 cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
143} 168}
144 169
145#ifdef CONFIG_HOTPLUG_CPU 170#ifdef CONFIG_HOTPLUG_CPU
@@ -149,8 +174,8 @@ static void unmap_cpu_from_node(unsigned long cpu)
149 174
150 dbg("removing cpu %lu from node %d\n", cpu, node); 175 dbg("removing cpu %lu from node %d\n", cpu, node);
151 176
152 if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { 177 if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
153 cpu_clear(cpu, numa_cpumask_lookup_table[node]); 178 cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
154 } else { 179 } else {
155 printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n", 180 printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
156 cpu, node); 181 cpu, node);
@@ -246,7 +271,8 @@ static int __init find_min_common_depth(void)
246 const unsigned int *ref_points; 271 const unsigned int *ref_points;
247 struct device_node *rtas_root; 272 struct device_node *rtas_root;
248 unsigned int len; 273 unsigned int len;
249 struct device_node *options; 274 struct device_node *chosen;
275 const char *vec5;
250 276
251 rtas_root = of_find_node_by_path("/rtas"); 277 rtas_root = of_find_node_by_path("/rtas");
252 278
@@ -264,14 +290,17 @@ static int __init find_min_common_depth(void)
264 "ibm,associativity-reference-points", &len); 290 "ibm,associativity-reference-points", &len);
265 291
266 /* 292 /*
267 * For type 1 affinity information we want the first field 293 * For form 1 affinity information we want the first field
268 */ 294 */
269 options = of_find_node_by_path("/options"); 295#define VEC5_AFFINITY_BYTE 5
270 if (options) { 296#define VEC5_AFFINITY 0x80
271 const char *str; 297 chosen = of_find_node_by_path("/chosen");
272 str = of_get_property(options, "ibm,associativity-form", NULL); 298 if (chosen) {
273 if (str && !strcmp(str, "1")) 299 vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
274 index = 0; 300 if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
301 dbg("Using form 1 affinity\n");
302 index = 0;
303 }
275 } 304 }
276 305
277 if ((len >= 2 * sizeof(unsigned int)) && ref_points) { 306 if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
@@ -750,8 +779,9 @@ void __init dump_numa_cpu_topology(void)
750 * If we used a CPU iterator here we would miss printing 779 * If we used a CPU iterator here we would miss printing
751 * the holes in the cpumap. 780 * the holes in the cpumap.
752 */ 781 */
753 for (cpu = 0; cpu < NR_CPUS; cpu++) { 782 for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
754 if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { 783 if (cpumask_test_cpu(cpu,
784 node_to_cpumask_map[node])) {
755 if (count == 0) 785 if (count == 0)
756 printk(" %u", cpu); 786 printk(" %u", cpu);
757 ++count; 787 ++count;
@@ -763,7 +793,7 @@ void __init dump_numa_cpu_topology(void)
763 } 793 }
764 794
765 if (count > 1) 795 if (count > 1)
766 printk("-%u", NR_CPUS - 1); 796 printk("-%u", nr_cpu_ids - 1);
767 printk("\n"); 797 printk("\n");
768 } 798 }
769} 799}
@@ -939,10 +969,6 @@ void __init do_init_bootmem(void)
939 else 969 else
940 dump_numa_memory_topology(); 970 dump_numa_memory_topology();
941 971
942 register_cpu_notifier(&ppc64_numa_nb);
943 cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
944 (void *)(unsigned long)boot_cpuid);
945
946 for_each_online_node(nid) { 972 for_each_online_node(nid) {
947 unsigned long start_pfn, end_pfn; 973 unsigned long start_pfn, end_pfn;
948 void *bootmem_vaddr; 974 void *bootmem_vaddr;
@@ -996,6 +1022,16 @@ void __init do_init_bootmem(void)
996 } 1022 }
997 1023
998 init_bootmem_done = 1; 1024 init_bootmem_done = 1;
1025
1026 /*
1027 * Now bootmem is initialised we can create the node to cpumask
1028 * lookup tables and setup the cpu callback to populate them.
1029 */
1030 setup_node_to_cpumask_map();
1031
1032 register_cpu_notifier(&ppc64_numa_nb);
1033 cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
1034 (void *)(unsigned long)boot_cpuid);
999} 1035}
1000 1036
1001void __init paging_init(void) 1037void __init paging_init(void)