diff options
author | Ashok Raj <ashok.raj@intel.com> | 2005-06-25 17:55:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-25 19:24:31 -0400 |
commit | cb0cd8d49a9b81aff7a02e2ed826b5cfdfe9a172 (patch) | |
tree | b61021353fe396a060483f7050b38cfed43a7590 /arch | |
parent | 76e4f660d9f4c6d1bb473f72be2988c35eaca948 (diff) |
[PATCH] x86_64: CPU hotplug sibling map cleanup
This patch is a minor cleanup to the cpu sibling/core map. It is required
that this setup happens on a per-cpu bringup time.
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
Acked-by: Andi Kleen <ak@muc.de>
Acked-by: Zwane Mwaikambo <zwane@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 84 |
1 files changed, 36 insertions, 48 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 5a3f955b6576..571a55462fa0 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -445,6 +445,33 @@ void __cpuinit smp_callin(void) | |||
445 | cpu_set(cpuid, cpu_callin_map); | 445 | cpu_set(cpuid, cpu_callin_map); |
446 | } | 446 | } |
447 | 447 | ||
448 | static inline void set_cpu_sibling_map(int cpu) | ||
449 | { | ||
450 | int i; | ||
451 | |||
452 | if (smp_num_siblings > 1) { | ||
453 | for_each_cpu(i) { | ||
454 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
455 | cpu_set(i, cpu_sibling_map[cpu]); | ||
456 | cpu_set(cpu, cpu_sibling_map[i]); | ||
457 | } | ||
458 | } | ||
459 | } else { | ||
460 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
461 | } | ||
462 | |||
463 | if (current_cpu_data.x86_num_cores > 1) { | ||
464 | for_each_cpu(i) { | ||
465 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | ||
466 | cpu_set(i, cpu_core_map[cpu]); | ||
467 | cpu_set(cpu, cpu_core_map[i]); | ||
468 | } | ||
469 | } | ||
470 | } else { | ||
471 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
472 | } | ||
473 | } | ||
474 | |||
448 | /* | 475 | /* |
449 | * Setup code on secondary processor (after comming out of the trampoline) | 476 | * Setup code on secondary processor (after comming out of the trampoline) |
450 | */ | 477 | */ |
@@ -475,6 +502,12 @@ void __cpuinit start_secondary(void) | |||
475 | enable_APIC_timer(); | 502 | enable_APIC_timer(); |
476 | 503 | ||
477 | /* | 504 | /* |
505 | * The sibling maps must be set before turing the online map on for | ||
506 | * this cpu | ||
507 | */ | ||
508 | set_cpu_sibling_map(smp_processor_id()); | ||
509 | |||
510 | /* | ||
478 | * Allow the master to continue. | 511 | * Allow the master to continue. |
479 | */ | 512 | */ |
480 | cpu_set(smp_processor_id(), cpu_online_map); | 513 | cpu_set(smp_processor_id(), cpu_online_map); |
@@ -817,51 +850,6 @@ cycles_t cacheflush_time; | |||
817 | unsigned long cache_decay_ticks; | 850 | unsigned long cache_decay_ticks; |
818 | 851 | ||
819 | /* | 852 | /* |
820 | * Construct cpu_sibling_map[], so that we can tell the sibling CPU | ||
821 | * on SMT systems efficiently. | ||
822 | */ | ||
823 | static __cpuinit void detect_siblings(void) | ||
824 | { | ||
825 | int cpu; | ||
826 | |||
827 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | ||
828 | cpus_clear(cpu_sibling_map[cpu]); | ||
829 | cpus_clear(cpu_core_map[cpu]); | ||
830 | } | ||
831 | |||
832 | for_each_online_cpu (cpu) { | ||
833 | struct cpuinfo_x86 *c = cpu_data + cpu; | ||
834 | int siblings = 0; | ||
835 | int i; | ||
836 | if (smp_num_siblings > 1) { | ||
837 | for_each_online_cpu (i) { | ||
838 | if (cpu_core_id[cpu] == cpu_core_id[i]) { | ||
839 | siblings++; | ||
840 | cpu_set(i, cpu_sibling_map[cpu]); | ||
841 | } | ||
842 | } | ||
843 | } else { | ||
844 | siblings++; | ||
845 | cpu_set(cpu, cpu_sibling_map[cpu]); | ||
846 | } | ||
847 | |||
848 | if (siblings != smp_num_siblings) { | ||
849 | printk(KERN_WARNING | ||
850 | "WARNING: %d siblings found for CPU%d, should be %d\n", | ||
851 | siblings, cpu, smp_num_siblings); | ||
852 | smp_num_siblings = siblings; | ||
853 | } | ||
854 | if (c->x86_num_cores > 1) { | ||
855 | for_each_online_cpu(i) { | ||
856 | if (phys_proc_id[cpu] == phys_proc_id[i]) | ||
857 | cpu_set(i, cpu_core_map[cpu]); | ||
858 | } | ||
859 | } else | ||
860 | cpu_core_map[cpu] = cpu_sibling_map[cpu]; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | /* | ||
865 | * Cleanup possible dangling ends... | 853 | * Cleanup possible dangling ends... |
866 | */ | 854 | */ |
867 | static __cpuinit void smp_cleanup_boot(void) | 855 | static __cpuinit void smp_cleanup_boot(void) |
@@ -1048,6 +1036,8 @@ void __init smp_prepare_boot_cpu(void) | |||
1048 | int me = smp_processor_id(); | 1036 | int me = smp_processor_id(); |
1049 | cpu_set(me, cpu_online_map); | 1037 | cpu_set(me, cpu_online_map); |
1050 | cpu_set(me, cpu_callout_map); | 1038 | cpu_set(me, cpu_callout_map); |
1039 | cpu_set(0, cpu_sibling_map[0]); | ||
1040 | cpu_set(0, cpu_core_map[0]); | ||
1051 | } | 1041 | } |
1052 | 1042 | ||
1053 | /* | 1043 | /* |
@@ -1107,7 +1097,6 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
1107 | setup_ioapic_dest(); | 1097 | setup_ioapic_dest(); |
1108 | #endif | 1098 | #endif |
1109 | 1099 | ||
1110 | detect_siblings(); | ||
1111 | time_init_gtod(); | 1100 | time_init_gtod(); |
1112 | 1101 | ||
1113 | check_nmi_watchdog(); | 1102 | check_nmi_watchdog(); |
@@ -1115,8 +1104,7 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
1115 | 1104 | ||
1116 | #ifdef CONFIG_HOTPLUG_CPU | 1105 | #ifdef CONFIG_HOTPLUG_CPU |
1117 | 1106 | ||
1118 | static void | 1107 | static void remove_siblinginfo(int cpu) |
1119 | remove_siblinginfo(int cpu) | ||
1120 | { | 1108 | { |
1121 | int sibling; | 1109 | int sibling; |
1122 | 1110 | ||