diff options
author | Anton Blanchard <anton@samba.org> | 2010-04-26 11:32:41 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-05-06 03:41:56 -0400 |
commit | cc1ba8ea6dde3f049b2b365d8fdc13976aee25cb (patch) | |
tree | 89276abd9b89c39967a04ec39dcfc1ca2a924f6d /arch | |
parent | e6532c63cc3dbefc79936fc9c9c68a151004fe46 (diff) |
powerpc/cpumask: Dynamically allocate cpu_sibling_map and cpu_core_map cpumasks
Dynamically allocate cpu_sibling_map and cpu_core_map cpumasks.
We don't need to set_cpu_online() the boot cpu in smp_prepare_boot_cpu,
init/main.c does it for us.
We also postpone setting of the boot cpu in cpu_sibling_map and cpu_core_map
until when the memory allocator is available (smp_prepare_cpus), similar
to x86.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/smp.h | 16 | ||||
-rw-r--r-- | arch/powerpc/include/asm/topology.h | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/smp.c | 42 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/cbe_cpufreq.c | 2 |
4 files changed, 40 insertions, 24 deletions
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 4d332296c40d..66e237bbe15f 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h | |||
@@ -68,8 +68,19 @@ static inline void set_hard_smp_processor_id(int cpu, int phys) | |||
68 | } | 68 | } |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); | 71 | DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); |
72 | DECLARE_PER_CPU(cpumask_t, cpu_core_map); | 72 | DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); |
73 | |||
74 | static inline struct cpumask *cpu_sibling_mask(int cpu) | ||
75 | { | ||
76 | return per_cpu(cpu_sibling_map, cpu); | ||
77 | } | ||
78 | |||
79 | static inline struct cpumask *cpu_core_mask(int cpu) | ||
80 | { | ||
81 | return per_cpu(cpu_core_map, cpu); | ||
82 | } | ||
83 | |||
73 | extern int cpu_to_core_id(int cpu); | 84 | extern int cpu_to_core_id(int cpu); |
74 | 85 | ||
75 | /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. | 86 | /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. |
@@ -93,7 +104,6 @@ void smp_init_pSeries(void); | |||
93 | void smp_init_cell(void); | 104 | void smp_init_cell(void); |
94 | void smp_init_celleb(void); | 105 | void smp_init_celleb(void); |
95 | void smp_setup_cpu_maps(void); | 106 | void smp_setup_cpu_maps(void); |
96 | void smp_setup_cpu_sibling_map(void); | ||
97 | 107 | ||
98 | extern int __cpu_disable(void); | 108 | extern int __cpu_disable(void); |
99 | extern void __cpu_die(unsigned int cpu); | 109 | extern void __cpu_die(unsigned int cpu); |
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index a7d769491555..789599b69960 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h | |||
@@ -112,8 +112,8 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev, | |||
112 | #ifdef CONFIG_PPC64 | 112 | #ifdef CONFIG_PPC64 |
113 | #include <asm/smp.h> | 113 | #include <asm/smp.h> |
114 | 114 | ||
115 | #define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) | 115 | #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) |
116 | #define topology_core_cpumask(cpu) (&per_cpu(cpu_core_map, cpu)) | 116 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) |
117 | #define topology_core_id(cpu) (cpu_to_core_id(cpu)) | 117 | #define topology_core_id(cpu) (cpu_to_core_id(cpu)) |
118 | #endif | 118 | #endif |
119 | #endif | 119 | #endif |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 62e82c25c583..39babb1e2ce1 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -59,8 +59,8 @@ | |||
59 | 59 | ||
60 | struct thread_info *secondary_ti; | 60 | struct thread_info *secondary_ti; |
61 | 61 | ||
62 | DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; | 62 | DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); |
63 | DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE; | 63 | DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); |
64 | 64 | ||
65 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | 65 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); |
66 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); | 66 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); |
@@ -271,6 +271,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
271 | smp_store_cpu_info(boot_cpuid); | 271 | smp_store_cpu_info(boot_cpuid); |
272 | cpu_callin_map[boot_cpuid] = 1; | 272 | cpu_callin_map[boot_cpuid] = 1; |
273 | 273 | ||
274 | for_each_possible_cpu(cpu) { | ||
275 | zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu), | ||
276 | GFP_KERNEL, cpu_to_node(cpu)); | ||
277 | zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), | ||
278 | GFP_KERNEL, cpu_to_node(cpu)); | ||
279 | } | ||
280 | |||
281 | cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); | ||
282 | cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); | ||
283 | |||
274 | if (smp_ops) | 284 | if (smp_ops) |
275 | if (smp_ops->probe) | 285 | if (smp_ops->probe) |
276 | max_cpus = smp_ops->probe(); | 286 | max_cpus = smp_ops->probe(); |
@@ -289,10 +299,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
289 | void __devinit smp_prepare_boot_cpu(void) | 299 | void __devinit smp_prepare_boot_cpu(void) |
290 | { | 300 | { |
291 | BUG_ON(smp_processor_id() != boot_cpuid); | 301 | BUG_ON(smp_processor_id() != boot_cpuid); |
292 | |||
293 | set_cpu_online(boot_cpuid, true); | ||
294 | cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid)); | ||
295 | cpu_set(boot_cpuid, per_cpu(cpu_core_map, boot_cpuid)); | ||
296 | #ifdef CONFIG_PPC64 | 302 | #ifdef CONFIG_PPC64 |
297 | paca[boot_cpuid].__current = current; | 303 | paca[boot_cpuid].__current = current; |
298 | #endif | 304 | #endif |
@@ -525,15 +531,15 @@ int __devinit start_secondary(void *unused) | |||
525 | for (i = 0; i < threads_per_core; i++) { | 531 | for (i = 0; i < threads_per_core; i++) { |
526 | if (cpu_is_offline(base + i)) | 532 | if (cpu_is_offline(base + i)) |
527 | continue; | 533 | continue; |
528 | cpu_set(cpu, per_cpu(cpu_sibling_map, base + i)); | 534 | cpumask_set_cpu(cpu, cpu_sibling_mask(base + i)); |
529 | cpu_set(base + i, per_cpu(cpu_sibling_map, cpu)); | 535 | cpumask_set_cpu(base + i, cpu_sibling_mask(cpu)); |
530 | 536 | ||
531 | /* cpu_core_map should be a superset of | 537 | /* cpu_core_map should be a superset of |
532 | * cpu_sibling_map even if we don't have cache | 538 | * cpu_sibling_map even if we don't have cache |
533 | * information, so update the former here, too. | 539 | * information, so update the former here, too. |
534 | */ | 540 | */ |
535 | cpu_set(cpu, per_cpu(cpu_core_map, base +i)); | 541 | cpumask_set_cpu(cpu, cpu_core_mask(base + i)); |
536 | cpu_set(base + i, per_cpu(cpu_core_map, cpu)); | 542 | cpumask_set_cpu(base + i, cpu_core_mask(cpu)); |
537 | } | 543 | } |
538 | l2_cache = cpu_to_l2cache(cpu); | 544 | l2_cache = cpu_to_l2cache(cpu); |
539 | for_each_online_cpu(i) { | 545 | for_each_online_cpu(i) { |
@@ -541,8 +547,8 @@ int __devinit start_secondary(void *unused) | |||
541 | if (!np) | 547 | if (!np) |
542 | continue; | 548 | continue; |
543 | if (np == l2_cache) { | 549 | if (np == l2_cache) { |
544 | cpu_set(cpu, per_cpu(cpu_core_map, i)); | 550 | cpumask_set_cpu(cpu, cpu_core_mask(i)); |
545 | cpu_set(i, per_cpu(cpu_core_map, cpu)); | 551 | cpumask_set_cpu(i, cpu_core_mask(cpu)); |
546 | } | 552 | } |
547 | of_node_put(np); | 553 | of_node_put(np); |
548 | } | 554 | } |
@@ -602,10 +608,10 @@ int __cpu_disable(void) | |||
602 | /* Update sibling maps */ | 608 | /* Update sibling maps */ |
603 | base = cpu_first_thread_in_core(cpu); | 609 | base = cpu_first_thread_in_core(cpu); |
604 | for (i = 0; i < threads_per_core; i++) { | 610 | for (i = 0; i < threads_per_core; i++) { |
605 | cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i)); | 611 | cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); |
606 | cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu)); | 612 | cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); |
607 | cpu_clear(cpu, per_cpu(cpu_core_map, base +i)); | 613 | cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); |
608 | cpu_clear(base + i, per_cpu(cpu_core_map, cpu)); | 614 | cpumask_clear_cpu(base + i, cpu_core_mask(cpu)); |
609 | } | 615 | } |
610 | 616 | ||
611 | l2_cache = cpu_to_l2cache(cpu); | 617 | l2_cache = cpu_to_l2cache(cpu); |
@@ -614,8 +620,8 @@ int __cpu_disable(void) | |||
614 | if (!np) | 620 | if (!np) |
615 | continue; | 621 | continue; |
616 | if (np == l2_cache) { | 622 | if (np == l2_cache) { |
617 | cpu_clear(cpu, per_cpu(cpu_core_map, i)); | 623 | cpumask_clear_cpu(cpu, cpu_core_mask(i)); |
618 | cpu_clear(i, per_cpu(cpu_core_map, cpu)); | 624 | cpumask_clear_cpu(i, cpu_core_mask(cpu)); |
619 | } | 625 | } |
620 | of_node_put(np); | 626 | of_node_put(np); |
621 | } | 627 | } |
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index e6506cd0ff94..bfa2c0cb3d1e 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c | |||
@@ -118,7 +118,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
118 | policy->cur = cbe_freqs[cur_pmode].frequency; | 118 | policy->cur = cbe_freqs[cur_pmode].frequency; |
119 | 119 | ||
120 | #ifdef CONFIG_SMP | 120 | #ifdef CONFIG_SMP |
121 | cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu)); | 121 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); | 124 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); |