diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-06-17 03:12:03 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 01:47:37 -0400 |
commit | 0beefa208bb3a9e581a60125703409ebe6f7fa53 (patch) | |
tree | 0bfdec0cfd70031a70704ced8386c10c05fc034c /arch/x86/kernel/process.c | |
parent | aa276e1cafb3ce9d01d1e837bcd67e92616013ac (diff) |
x86: add C1E aware idle function, fix
On Tue, 17 Jun 2008, Rafael J. Wysocki wrote:
>
> BTW, with the C1E patches reverted I don't get the
> WARNING: at /home/rafael/src/linux-next/kernel/smp.c:215 smp_call_function_single+0x3d/0xa2
> in the log. Thomas?
The BROADCAST_FORCE notification uses smp_function_call and therefor
must be run with interrupts enabled.
While at it, add a comment for the BROADCAST_EXIT notifier as well.
Reported-and-bisected-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 68ad3539b14..4061d63aabe 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -267,17 +267,29 @@ static void c1e_idle(void) | |||
267 | 267 | ||
268 | if (!cpu_isset(cpu, c1e_mask)) { | 268 | if (!cpu_isset(cpu, c1e_mask)) { |
269 | cpu_set(cpu, c1e_mask); | 269 | cpu_set(cpu, c1e_mask); |
270 | /* Force broadcast so ACPI can not interfere */ | 270 | /* |
271 | * Force broadcast so ACPI can not interfere. Needs | ||
272 | * to run with interrupts enabled as it uses | ||
273 | * smp_function_call. | ||
274 | */ | ||
275 | local_irq_enable(); | ||
271 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | 276 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, |
272 | &cpu); | 277 | &cpu); |
273 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", | 278 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", |
274 | cpu); | 279 | cpu); |
280 | local_irq_disable(); | ||
275 | } | 281 | } |
276 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 282 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
283 | |||
277 | default_idle(); | 284 | default_idle(); |
278 | local_irq_disable(); | 285 | |
279 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | 286 | /* |
280 | local_irq_enable(); | 287 | * The switch back from broadcast mode needs to be |
288 | * called with interrupts disabled. | ||
289 | */ | ||
290 | local_irq_disable(); | ||
291 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | ||
292 | local_irq_enable(); | ||
281 | } else | 293 | } else |
282 | default_idle(); | 294 | default_idle(); |
283 | } | 295 | } |