diff options
Diffstat (limited to 'arch/powerpc/mm/numa.c')
-rw-r--r-- | arch/powerpc/mm/numa.c | 78 |
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 | ||
35 | int numa_cpu_lookup_table[NR_CPUS]; | 35 | int numa_cpu_lookup_table[NR_CPUS]; |
36 | cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES]; | 36 | cpumask_var_t node_to_cpumask_map[MAX_NUMNODES]; |
37 | struct pglist_data *node_data[MAX_NUMNODES]; | 37 | struct pglist_data *node_data[MAX_NUMNODES]; |
38 | 38 | ||
39 | EXPORT_SYMBOL(numa_cpu_lookup_table); | 39 | EXPORT_SYMBOL(numa_cpu_lookup_table); |
40 | EXPORT_SYMBOL(numa_cpumask_lookup_table); | 40 | EXPORT_SYMBOL(node_to_cpumask_map); |
41 | EXPORT_SYMBOL(node_data); | 41 | EXPORT_SYMBOL(node_data); |
42 | 42 | ||
43 | static int min_common_depth; | 43 | static int min_common_depth; |
44 | static int n_mem_addr_cells, n_mem_size_cells; | 44 | static 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 | */ | ||
52 | static 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 | |||
46 | static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn, | 71 | static 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 | ||
1001 | void __init paging_init(void) | 1037 | void __init paging_init(void) |