diff options
Diffstat (limited to 'arch/x86_64/kernel/smpboot.c')
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 71a7222cf9ce..4e9755179ecf 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -63,13 +63,11 @@ | |||
63 | 63 | ||
64 | /* Number of siblings per CPU package */ | 64 | /* Number of siblings per CPU package */ |
65 | int smp_num_siblings = 1; | 65 | int smp_num_siblings = 1; |
66 | /* Package ID of each logical CPU */ | 66 | EXPORT_SYMBOL(smp_num_siblings); |
67 | u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
68 | /* core ID of each logical CPU */ | ||
69 | u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; | ||
70 | 67 | ||
71 | /* Last level cache ID of each logical CPU */ | 68 | /* Last level cache ID of each logical CPU */ |
72 | u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; | 69 | u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; |
70 | EXPORT_SYMBOL(cpu_llc_id); | ||
73 | 71 | ||
74 | /* Bitmask of currently online CPUs */ | 72 | /* Bitmask of currently online CPUs */ |
75 | cpumask_t cpu_online_map __read_mostly; | 73 | cpumask_t cpu_online_map __read_mostly; |
@@ -82,18 +80,21 @@ EXPORT_SYMBOL(cpu_online_map); | |||
82 | */ | 80 | */ |
83 | cpumask_t cpu_callin_map; | 81 | cpumask_t cpu_callin_map; |
84 | cpumask_t cpu_callout_map; | 82 | cpumask_t cpu_callout_map; |
83 | EXPORT_SYMBOL(cpu_callout_map); | ||
85 | 84 | ||
86 | cpumask_t cpu_possible_map; | 85 | cpumask_t cpu_possible_map; |
87 | EXPORT_SYMBOL(cpu_possible_map); | 86 | EXPORT_SYMBOL(cpu_possible_map); |
88 | 87 | ||
89 | /* Per CPU bogomips and other parameters */ | 88 | /* Per CPU bogomips and other parameters */ |
90 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; | 89 | struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; |
90 | EXPORT_SYMBOL(cpu_data); | ||
91 | 91 | ||
92 | /* Set when the idlers are all forked */ | 92 | /* Set when the idlers are all forked */ |
93 | int smp_threads_ready; | 93 | int smp_threads_ready; |
94 | 94 | ||
95 | /* representing HT siblings of each logical CPU */ | 95 | /* representing HT siblings of each logical CPU */ |
96 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; | 96 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; |
97 | EXPORT_SYMBOL(cpu_sibling_map); | ||
97 | 98 | ||
98 | /* representing HT and core siblings of each logical CPU */ | 99 | /* representing HT and core siblings of each logical CPU */ |
99 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly; | 100 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly; |
@@ -472,8 +473,8 @@ static inline void set_cpu_sibling_map(int cpu) | |||
472 | 473 | ||
473 | if (smp_num_siblings > 1) { | 474 | if (smp_num_siblings > 1) { |
474 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 475 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
475 | if (phys_proc_id[cpu] == phys_proc_id[i] && | 476 | if (c[cpu].phys_proc_id == c[i].phys_proc_id && |
476 | cpu_core_id[cpu] == cpu_core_id[i]) { | 477 | c[cpu].cpu_core_id == c[i].cpu_core_id) { |
477 | cpu_set(i, cpu_sibling_map[cpu]); | 478 | cpu_set(i, cpu_sibling_map[cpu]); |
478 | cpu_set(cpu, cpu_sibling_map[i]); | 479 | cpu_set(cpu, cpu_sibling_map[i]); |
479 | cpu_set(i, cpu_core_map[cpu]); | 480 | cpu_set(i, cpu_core_map[cpu]); |
@@ -500,7 +501,7 @@ static inline void set_cpu_sibling_map(int cpu) | |||
500 | cpu_set(i, c[cpu].llc_shared_map); | 501 | cpu_set(i, c[cpu].llc_shared_map); |
501 | cpu_set(cpu, c[i].llc_shared_map); | 502 | cpu_set(cpu, c[i].llc_shared_map); |
502 | } | 503 | } |
503 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | 504 | if (c[cpu].phys_proc_id == c[i].phys_proc_id) { |
504 | cpu_set(i, cpu_core_map[cpu]); | 505 | cpu_set(i, cpu_core_map[cpu]); |
505 | cpu_set(cpu, cpu_core_map[i]); | 506 | cpu_set(cpu, cpu_core_map[i]); |
506 | /* | 507 | /* |
@@ -797,6 +798,8 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) | |||
797 | } | 798 | } |
798 | 799 | ||
799 | 800 | ||
801 | alternatives_smp_switch(1); | ||
802 | |||
800 | c_idle.idle = get_idle_for_cpu(cpu); | 803 | c_idle.idle = get_idle_for_cpu(cpu); |
801 | 804 | ||
802 | if (c_idle.idle) { | 805 | if (c_idle.idle) { |
@@ -1199,8 +1202,8 @@ static void remove_siblinginfo(int cpu) | |||
1199 | cpu_clear(cpu, cpu_sibling_map[sibling]); | 1202 | cpu_clear(cpu, cpu_sibling_map[sibling]); |
1200 | cpus_clear(cpu_sibling_map[cpu]); | 1203 | cpus_clear(cpu_sibling_map[cpu]); |
1201 | cpus_clear(cpu_core_map[cpu]); | 1204 | cpus_clear(cpu_core_map[cpu]); |
1202 | phys_proc_id[cpu] = BAD_APICID; | 1205 | c[cpu].phys_proc_id = 0; |
1203 | cpu_core_id[cpu] = BAD_APICID; | 1206 | c[cpu].cpu_core_id = 0; |
1204 | cpu_clear(cpu, cpu_sibling_setup_map); | 1207 | cpu_clear(cpu, cpu_sibling_setup_map); |
1205 | } | 1208 | } |
1206 | 1209 | ||
@@ -1259,6 +1262,8 @@ void __cpu_die(unsigned int cpu) | |||
1259 | /* They ack this in play_dead by setting CPU_DEAD */ | 1262 | /* They ack this in play_dead by setting CPU_DEAD */ |
1260 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { | 1263 | if (per_cpu(cpu_state, cpu) == CPU_DEAD) { |
1261 | printk ("CPU %d is now offline\n", cpu); | 1264 | printk ("CPU %d is now offline\n", cpu); |
1265 | if (1 == num_online_cpus()) | ||
1266 | alternatives_smp_switch(0); | ||
1262 | return; | 1267 | return; |
1263 | } | 1268 | } |
1264 | msleep(100); | 1269 | msleep(100); |