aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/process.c')
-rw-r--r--arch/i386/kernel/process.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index aea2ce1145df..5f8cfa6b7940 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -13,6 +13,7 @@
13 13
14#include <stdarg.h> 14#include <stdarg.h>
15 15
16#include <linux/cpu.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/sched.h> 18#include <linux/sched.h>
18#include <linux/fs.h> 19#include <linux/fs.h>
@@ -55,6 +56,9 @@
55#include <linux/irq.h> 56#include <linux/irq.h>
56#include <linux/err.h> 57#include <linux/err.h>
57 58
59#include <asm/tlbflush.h>
60#include <asm/cpu.h>
61
58asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 62asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
59 63
60static int hlt_counter; 64static int hlt_counter;
@@ -143,14 +147,42 @@ static void poll_idle (void)
143 } 147 }
144} 148}
145 149
150#ifdef CONFIG_HOTPLUG_CPU
151#include <asm/nmi.h>
152/* We don't actually take CPU down, just spin without interrupts. */
153static inline void play_dead(void)
154{
155 /* This must be done before dead CPU ack */
156 cpu_exit_clear();
157 wbinvd();
158 mb();
159 /* Ack it */
160 __get_cpu_var(cpu_state) = CPU_DEAD;
161
162 /*
163 * With physical CPU hotplug, we should halt the cpu
164 */
165 local_irq_disable();
166 while (1)
167 __asm__ __volatile__("hlt":::"memory");
168}
169#else
170static inline void play_dead(void)
171{
172 BUG();
173}
174#endif /* CONFIG_HOTPLUG_CPU */
175
146/* 176/*
147 * The idle thread. There's no useful work to be 177 * The idle thread. There's no useful work to be
148 * done, so just try to conserve power and have a 178 * done, so just try to conserve power and have a
149 * low exit latency (ie sit in a loop waiting for 179 * low exit latency (ie sit in a loop waiting for
150 * somebody to say that they'd like to reschedule) 180 * somebody to say that they'd like to reschedule)
151 */ 181 */
152void cpu_idle (void) 182void cpu_idle(void)
153{ 183{
184 int cpu = raw_smp_processor_id();
185
154 /* endless idle loop with no priority at all */ 186 /* endless idle loop with no priority at all */
155 while (1) { 187 while (1) {
156 while (!need_resched()) { 188 while (!need_resched()) {
@@ -165,6 +197,9 @@ void cpu_idle (void)
165 if (!idle) 197 if (!idle)
166 idle = default_idle; 198 idle = default_idle;
167 199
200 if (cpu_is_offline(cpu))
201 play_dead();
202
168 __get_cpu_var(irq_stat).idle_timestamp = jiffies; 203 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
169 idle(); 204 idle();
170 } 205 }
@@ -223,7 +258,7 @@ static void mwait_idle(void)
223 } 258 }
224} 259}
225 260
226void __init select_idle_routine(const struct cpuinfo_x86 *c) 261void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
227{ 262{
228 if (cpu_has(c, X86_FEATURE_MWAIT)) { 263 if (cpu_has(c, X86_FEATURE_MWAIT)) {
229 printk("monitor/mwait feature present.\n"); 264 printk("monitor/mwait feature present.\n");