aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Ostrovsky <boris.ostrovsky@oracle.com>2014-10-31 11:49:32 -0400
committerIngo Molnar <mingo@kernel.org>2014-11-10 05:16:40 -0500
commit54279552bd260532d90e7a59fbc931924bbb0f7b (patch)
treef62846d03d74c2571742ba070dcfc9664748078b
parente6023367d779060fddc9a52d1f474085b2b36298 (diff)
x86/core, x86/xen/smp: Use 'die_complete' completion when taking CPU down
Commit 2ed53c0d6cc9 ("x86/smpboot: Speed up suspend/resume by avoiding 100ms sleep for CPU offline during S3") introduced completions to CPU offlining process. These completions are not initialized on Xen kernels causing a panic in play_dead_common(). Move handling of die_complete into common routines to make them available to Xen guests. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> Reviewed-by: David Vrabel <david.vrabel@citrix.com> Cc: tianyu.lan@intel.com Cc: konrad.wilk@oracle.com Cc: xen-devel@lists.xenproject.org Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: http://lkml.kernel.org/r/1414770572-7950-1-git-send-email-boris.ostrovsky@oracle.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/smp.h1
-rw-r--r--arch/x86/kernel/smpboot.c15
-rw-r--r--arch/x86/xen/smp.c3
3 files changed, 15 insertions, 4 deletions
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 8cd27e08e23c..8cd1cc3bc835 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -150,6 +150,7 @@ static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
150} 150}
151 151
152void cpu_disable_common(void); 152void cpu_disable_common(void);
153void cpu_die_common(unsigned int cpu);
153void native_smp_prepare_boot_cpu(void); 154void native_smp_prepare_boot_cpu(void);
154void native_smp_prepare_cpus(unsigned int max_cpus); 155void native_smp_prepare_cpus(unsigned int max_cpus);
155void native_smp_cpus_done(unsigned int max_cpus); 156void native_smp_cpus_done(unsigned int max_cpus);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 4d2128ac70bd..668d8f2a8781 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1303,10 +1303,14 @@ static void __ref remove_cpu_from_maps(int cpu)
1303 numa_remove_cpu(cpu); 1303 numa_remove_cpu(cpu);
1304} 1304}
1305 1305
1306static DEFINE_PER_CPU(struct completion, die_complete);
1307
1306void cpu_disable_common(void) 1308void cpu_disable_common(void)
1307{ 1309{
1308 int cpu = smp_processor_id(); 1310 int cpu = smp_processor_id();
1309 1311
1312 init_completion(&per_cpu(die_complete, smp_processor_id()));
1313
1310 remove_siblinginfo(cpu); 1314 remove_siblinginfo(cpu);
1311 1315
1312 /* It's now safe to remove this processor from the online map */ 1316 /* It's now safe to remove this processor from the online map */
@@ -1316,8 +1320,6 @@ void cpu_disable_common(void)
1316 fixup_irqs(); 1320 fixup_irqs();
1317} 1321}
1318 1322
1319static DEFINE_PER_CPU(struct completion, die_complete);
1320
1321int native_cpu_disable(void) 1323int native_cpu_disable(void)
1322{ 1324{
1323 int ret; 1325 int ret;
@@ -1327,16 +1329,21 @@ int native_cpu_disable(void)
1327 return ret; 1329 return ret;
1328 1330
1329 clear_local_APIC(); 1331 clear_local_APIC();
1330 init_completion(&per_cpu(die_complete, smp_processor_id()));
1331 cpu_disable_common(); 1332 cpu_disable_common();
1332 1333
1333 return 0; 1334 return 0;
1334} 1335}
1335 1336
1337void cpu_die_common(unsigned int cpu)
1338{
1339 wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ);
1340}
1341
1336void native_cpu_die(unsigned int cpu) 1342void native_cpu_die(unsigned int cpu)
1337{ 1343{
1338 /* We don't do anything here: idle task is faking death itself. */ 1344 /* We don't do anything here: idle task is faking death itself. */
1339 wait_for_completion_timeout(&per_cpu(die_complete, cpu), HZ); 1345
1346 cpu_die_common(cpu);
1340 1347
1341 /* They ack this in play_dead() by setting CPU_DEAD */ 1348 /* They ack this in play_dead() by setting CPU_DEAD */
1342 if (per_cpu(cpu_state, cpu) == CPU_DEAD) { 1349 if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8650cdb53209..4c071aeb8417 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -510,6 +510,9 @@ static void xen_cpu_die(unsigned int cpu)
510 current->state = TASK_UNINTERRUPTIBLE; 510 current->state = TASK_UNINTERRUPTIBLE;
511 schedule_timeout(HZ/10); 511 schedule_timeout(HZ/10);
512 } 512 }
513
514 cpu_die_common(cpu);
515
513 xen_smp_intr_free(cpu); 516 xen_smp_intr_free(cpu);
514 xen_uninit_lock_cpu(cpu); 517 xen_uninit_lock_cpu(cpu);
515 xen_teardown_timer(cpu); 518 xen_teardown_timer(cpu);