aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2011-01-05 06:48:09 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 06:47:30 -0500
commitda7f51c11d5fedca9ba779ee220063ccb4f0a27e (patch)
treea8cd6d843e72128ad6bfef0f19ef601f27f56ba9
parentf230886b0b0f0ce604395481bea05f3c0ad8fc9e (diff)
[S390] smp/idle: call init_idle() before starting a new cpu
Call init_idle() which (re-)initializes the idle task structure before it gets used on a new cpu. That way we can also get rid of the odd preempt_enable_no_resched() call we have in the cpu offline path within cpu_idle(). That call prevented preempt count imbalances between cpu hotplug operations. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/smp.h3
-rw-r--r--arch/s390/kernel/process.c8
-rw-r--r--arch/s390/kernel/smp.c1
3 files changed, 5 insertions, 7 deletions
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index edc03cb9cd79..045e009fc164 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -20,7 +20,6 @@ extern void machine_power_off_smp(void);
20 20
21extern int __cpu_disable (void); 21extern int __cpu_disable (void);
22extern void __cpu_die (unsigned int cpu); 22extern void __cpu_die (unsigned int cpu);
23extern void cpu_die (void) __attribute__ ((noreturn));
24extern int __cpu_up (unsigned int cpu); 23extern int __cpu_up (unsigned int cpu);
25 24
26extern struct mutex smp_cpu_state_mutex; 25extern struct mutex smp_cpu_state_mutex;
@@ -71,8 +70,10 @@ static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
71 70
72#ifdef CONFIG_HOTPLUG_CPU 71#ifdef CONFIG_HOTPLUG_CPU
73extern int smp_rescan_cpus(void); 72extern int smp_rescan_cpus(void);
73extern void __noreturn cpu_die(void);
74#else 74#else
75static inline int smp_rescan_cpus(void) { return 0; } 75static inline int smp_rescan_cpus(void) { return 0; }
76static inline void cpu_die(void) { }
76#endif 77#endif
77 78
78#endif /* __ASM_SMP_H */ 79#endif /* __ASM_SMP_H */
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index b825b3e1cb17..c2fffb57d727 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -42,6 +42,7 @@
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/timer.h> 43#include <asm/timer.h>
44#include <asm/nmi.h> 44#include <asm/nmi.h>
45#include <asm/smp.h>
45#include "entry.h" 46#include "entry.h"
46 47
47asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); 48asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -76,13 +77,8 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
76 */ 77 */
77static void default_idle(void) 78static void default_idle(void)
78{ 79{
79 /* CPU is going idle. */ 80 if (cpu_is_offline(smp_processor_id()))
80#ifdef CONFIG_HOTPLUG_CPU
81 if (cpu_is_offline(smp_processor_id())) {
82 preempt_enable_no_resched();
83 cpu_die(); 81 cpu_die();
84 }
85#endif
86 local_irq_disable(); 82 local_irq_disable();
87 if (need_resched()) { 83 if (need_resched()) {
88 local_irq_enable(); 84 local_irq_enable();
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8e84b5af49ba..10766be524eb 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -575,6 +575,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
575 idle = c_idle.idle; 575 idle = c_idle.idle;
576 current_set[cpu] = c_idle.idle; 576 current_set[cpu] = c_idle.idle;
577 } 577 }
578 init_idle(idle, cpu);
578 if (smp_alloc_lowcore(cpu)) 579 if (smp_alloc_lowcore(cpu))
579 return -ENOMEM; 580 return -ENOMEM;
580 do { 581 do {