diff options
author | Nathan Lynch <ntl@pobox.com> | 2008-07-27 01:24:52 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-28 02:30:49 -0400 |
commit | e2075f79a99b45a6cc10de021c93f07212098a84 (patch) | |
tree | 8c3ccb423f706336741734d0758219028d765396 /arch/powerpc/kernel/smp.c | |
parent | 9ba1984ead5d25c93d241e0ee43f8f6a252f60d9 (diff) |
powerpc: Update cpu_sibling_maps dynamically
Rather doing one initialization pass over all the per-cpu
cpu_sibling_maps at boot, update the maps at cpu online/offline time.
This is a behavior change -- the thread_siblings attribute now
reflects only online siblings, whereas it would display offline
siblings before. The new behavior matches that of x86, and is
arguably more useful.
Signed-off-by: Nathan Lynch <ntl@pobox.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index f5ae9fa222ea..3c4d07e5e06a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/smp.h> | 41 | #include <asm/smp.h> |
42 | #include <asm/time.h> | 42 | #include <asm/time.h> |
43 | #include <asm/machdep.h> | 43 | #include <asm/machdep.h> |
44 | #include <asm/cputhreads.h> | ||
44 | #include <asm/cputable.h> | 45 | #include <asm/cputable.h> |
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/mpic.h> | 47 | #include <asm/mpic.h> |
@@ -228,6 +229,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
228 | BUG_ON(smp_processor_id() != boot_cpuid); | 229 | BUG_ON(smp_processor_id() != boot_cpuid); |
229 | 230 | ||
230 | cpu_set(boot_cpuid, cpu_online_map); | 231 | cpu_set(boot_cpuid, cpu_online_map); |
232 | cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid)); | ||
231 | #ifdef CONFIG_PPC64 | 233 | #ifdef CONFIG_PPC64 |
232 | paca[boot_cpuid].__current = current; | 234 | paca[boot_cpuid].__current = current; |
233 | #endif | 235 | #endif |
@@ -380,6 +382,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
380 | int __devinit start_secondary(void *unused) | 382 | int __devinit start_secondary(void *unused) |
381 | { | 383 | { |
382 | unsigned int cpu = smp_processor_id(); | 384 | unsigned int cpu = smp_processor_id(); |
385 | int i, base; | ||
383 | 386 | ||
384 | atomic_inc(&init_mm.mm_count); | 387 | atomic_inc(&init_mm.mm_count); |
385 | current->active_mm = &init_mm; | 388 | current->active_mm = &init_mm; |
@@ -400,6 +403,14 @@ int __devinit start_secondary(void *unused) | |||
400 | 403 | ||
401 | ipi_call_lock(); | 404 | ipi_call_lock(); |
402 | cpu_set(cpu, cpu_online_map); | 405 | cpu_set(cpu, cpu_online_map); |
406 | /* Update sibling maps */ | ||
407 | base = cpu_first_thread_in_core(cpu); | ||
408 | for (i = 0; i < threads_per_core; i++) { | ||
409 | if (cpu_is_offline(base + i)) | ||
410 | continue; | ||
411 | cpu_set(cpu, per_cpu(cpu_sibling_map, base + i)); | ||
412 | cpu_set(base + i, per_cpu(cpu_sibling_map, cpu)); | ||
413 | } | ||
403 | ipi_call_unlock(); | 414 | ipi_call_unlock(); |
404 | 415 | ||
405 | local_irq_enable(); | 416 | local_irq_enable(); |
@@ -437,10 +448,25 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
437 | #ifdef CONFIG_HOTPLUG_CPU | 448 | #ifdef CONFIG_HOTPLUG_CPU |
438 | int __cpu_disable(void) | 449 | int __cpu_disable(void) |
439 | { | 450 | { |
440 | if (smp_ops->cpu_disable) | 451 | int cpu = smp_processor_id(); |
441 | return smp_ops->cpu_disable(); | 452 | int base, i; |
453 | int err; | ||
442 | 454 | ||
443 | return -ENOSYS; | 455 | if (!smp_ops->cpu_disable) |
456 | return -ENOSYS; | ||
457 | |||
458 | err = smp_ops->cpu_disable(); | ||
459 | if (err) | ||
460 | return err; | ||
461 | |||
462 | /* Update sibling maps */ | ||
463 | base = cpu_first_thread_in_core(cpu); | ||
464 | for (i = 0; i < threads_per_core; i++) { | ||
465 | cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i)); | ||
466 | cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu)); | ||
467 | } | ||
468 | |||
469 | return 0; | ||
444 | } | 470 | } |
445 | 471 | ||
446 | void __cpu_die(unsigned int cpu) | 472 | void __cpu_die(unsigned int cpu) |