diff options
author | Fenghua Yu <fenghua.yu@intel.com> | 2012-11-13 14:32:41 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-11-14 12:39:48 -0500 |
commit | 30106c174311b8cfaaa3186c7f6f9c36c62d17da (patch) | |
tree | 58a0c368ebd8ccc48dddc9b723ed1296b9e741db /arch/x86/kernel/smpboot.c | |
parent | 4d25031a81d3cd32edc00de6596db76cc4010685 (diff) |
x86, hotplug: Support functions for CPU0 online/offline
Add smp_store_boot_cpu_info() to store cpu info for BSP during boot time.
Now smp_store_cpu_info() stores cpu info for bringing up BSP or AP after
it's offline.
Continue to online CPU0 in native_cpu_up().
Continue to offline CPU0 in native_cpu_disable().
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: http://lkml.kernel.org/r/1352835171-3958-5-git-send-email-fenghua.yu@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c80a33bc528b..c297907f3c75 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -125,8 +125,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); | |||
125 | atomic_t init_deasserted; | 125 | atomic_t init_deasserted; |
126 | 126 | ||
127 | /* | 127 | /* |
128 | * Report back to the Boot Processor. | 128 | * Report back to the Boot Processor during boot time or to the caller processor |
129 | * Running on AP. | 129 | * during CPU online. |
130 | */ | 130 | */ |
131 | static void __cpuinit smp_callin(void) | 131 | static void __cpuinit smp_callin(void) |
132 | { | 132 | { |
@@ -279,19 +279,30 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
279 | cpu_idle(); | 279 | cpu_idle(); |
280 | } | 280 | } |
281 | 281 | ||
282 | void __init smp_store_boot_cpu_info(void) | ||
283 | { | ||
284 | int id = 0; /* CPU 0 */ | ||
285 | struct cpuinfo_x86 *c = &cpu_data(id); | ||
286 | |||
287 | *c = boot_cpu_data; | ||
288 | c->cpu_index = id; | ||
289 | } | ||
290 | |||
282 | /* | 291 | /* |
283 | * The bootstrap kernel entry code has set these up. Save them for | 292 | * The bootstrap kernel entry code has set these up. Save them for |
284 | * a given CPU | 293 | * a given CPU |
285 | */ | 294 | */ |
286 | |||
287 | void __cpuinit smp_store_cpu_info(int id) | 295 | void __cpuinit smp_store_cpu_info(int id) |
288 | { | 296 | { |
289 | struct cpuinfo_x86 *c = &cpu_data(id); | 297 | struct cpuinfo_x86 *c = &cpu_data(id); |
290 | 298 | ||
291 | *c = boot_cpu_data; | 299 | *c = boot_cpu_data; |
292 | c->cpu_index = id; | 300 | c->cpu_index = id; |
293 | if (id != 0) | 301 | /* |
294 | identify_secondary_cpu(c); | 302 | * During boot time, CPU0 has this setup already. Save the info when |
303 | * bringing up AP or offlined CPU0. | ||
304 | */ | ||
305 | identify_secondary_cpu(c); | ||
295 | } | 306 | } |
296 | 307 | ||
297 | static bool __cpuinit | 308 | static bool __cpuinit |
@@ -795,7 +806,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
795 | 806 | ||
796 | pr_debug("++++++++++++++++++++=_---CPU UP %u\n", cpu); | 807 | pr_debug("++++++++++++++++++++=_---CPU UP %u\n", cpu); |
797 | 808 | ||
798 | if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || | 809 | if (apicid == BAD_APICID || |
799 | !physid_isset(apicid, phys_cpu_present_map) || | 810 | !physid_isset(apicid, phys_cpu_present_map) || |
800 | !apic->apic_id_valid(apicid)) { | 811 | !apic->apic_id_valid(apicid)) { |
801 | pr_err("%s: bad cpu %d\n", __func__, cpu); | 812 | pr_err("%s: bad cpu %d\n", __func__, cpu); |
@@ -990,7 +1001,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
990 | /* | 1001 | /* |
991 | * Setup boot CPU information | 1002 | * Setup boot CPU information |
992 | */ | 1003 | */ |
993 | smp_store_cpu_info(0); /* Final full version of the data */ | 1004 | smp_store_boot_cpu_info(); /* Final full version of the data */ |
994 | cpumask_copy(cpu_callin_mask, cpumask_of(0)); | 1005 | cpumask_copy(cpu_callin_mask, cpumask_of(0)); |
995 | mb(); | 1006 | mb(); |
996 | 1007 | ||
@@ -1214,19 +1225,6 @@ void cpu_disable_common(void) | |||
1214 | 1225 | ||
1215 | int native_cpu_disable(void) | 1226 | int native_cpu_disable(void) |
1216 | { | 1227 | { |
1217 | int cpu = smp_processor_id(); | ||
1218 | |||
1219 | /* | ||
1220 | * Perhaps use cpufreq to drop frequency, but that could go | ||
1221 | * into generic code. | ||
1222 | * | ||
1223 | * We won't take down the boot processor on i386 due to some | ||
1224 | * interrupts only being able to be serviced by the BSP. | ||
1225 | * Especially so if we're not using an IOAPIC -zwane | ||
1226 | */ | ||
1227 | if (cpu == 0) | ||
1228 | return -EBUSY; | ||
1229 | |||
1230 | clear_local_APIC(); | 1228 | clear_local_APIC(); |
1231 | 1229 | ||
1232 | cpu_disable_common(); | 1230 | cpu_disable_common(); |