aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/apm.c6
-rw-r--r--arch/i386/kernel/process.c7
-rw-r--r--arch/ia64/kernel/process.c10
-rw-r--r--arch/x86_64/kernel/process.c6
-rw-r--r--drivers/acpi/processor_idle.c12
5 files changed, 34 insertions, 7 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index b75cff25de4b..199016927541 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -785,7 +785,11 @@ static int apm_do_idle(void)
785 polling = !!(current_thread_info()->status & TS_POLLING); 785 polling = !!(current_thread_info()->status & TS_POLLING);
786 if (polling) { 786 if (polling) {
787 current_thread_info()->status &= ~TS_POLLING; 787 current_thread_info()->status &= ~TS_POLLING;
788 smp_mb__after_clear_bit(); 788 /*
789 * TS_POLLING-cleared state must be visible before we
790 * test NEED_RESCHED:
791 */
792 smp_mb();
789 } 793 }
790 if (!need_resched()) { 794 if (!need_resched()) {
791 idled = 1; 795 idled = 1;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 99308510a17c..c641056233a6 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -102,7 +102,12 @@ void default_idle(void)
102{ 102{
103 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 103 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
104 current_thread_info()->status &= ~TS_POLLING; 104 current_thread_info()->status &= ~TS_POLLING;
105 smp_mb__after_clear_bit(); 105 /*
106 * TS_POLLING-cleared state must be visible before we
107 * test NEED_RESCHED:
108 */
109 smp_mb();
110
106 local_irq_disable(); 111 local_irq_disable();
107 if (!need_resched()) 112 if (!need_resched())
108 safe_halt(); /* enables interrupts racelessly */ 113 safe_halt(); /* enables interrupts racelessly */
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 51922b98086a..17685abaf496 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -268,10 +268,16 @@ cpu_idle (void)
268 268
269 /* endless idle loop with no priority at all */ 269 /* endless idle loop with no priority at all */
270 while (1) { 270 while (1) {
271 if (can_do_pal_halt) 271 if (can_do_pal_halt) {
272 current_thread_info()->status &= ~TS_POLLING; 272 current_thread_info()->status &= ~TS_POLLING;
273 else 273 /*
274 * TS_POLLING-cleared state must be visible before we
275 * test NEED_RESCHED:
276 */
277 smp_mb();
278 } else {
274 current_thread_info()->status |= TS_POLLING; 279 current_thread_info()->status |= TS_POLLING;
280 }
275 281
276 if (!need_resched()) { 282 if (!need_resched()) {
277 void (*idle)(void); 283 void (*idle)(void);
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index a418ee4c8c62..cbbc6adc1a92 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -109,7 +109,11 @@ void exit_idle(void)
109static void default_idle(void) 109static void default_idle(void)
110{ 110{
111 current_thread_info()->status &= ~TS_POLLING; 111 current_thread_info()->status &= ~TS_POLLING;
112 smp_mb__after_clear_bit(); 112 /*
113 * TS_POLLING-cleared state must be visible before we
114 * test NEED_RESCHED:
115 */
116 smp_mb();
113 local_irq_disable(); 117 local_irq_disable();
114 if (!need_resched()) { 118 if (!need_resched()) {
115 /* Enables interrupts one instruction before HLT. 119 /* Enables interrupts one instruction before HLT.
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 65b3f056ad89..6dac6050bb5a 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -211,7 +211,11 @@ acpi_processor_power_activate(struct acpi_processor *pr,
211static void acpi_safe_halt(void) 211static void acpi_safe_halt(void)
212{ 212{
213 current_thread_info()->status &= ~TS_POLLING; 213 current_thread_info()->status &= ~TS_POLLING;
214 smp_mb__after_clear_bit(); 214 /*
215 * TS_POLLING-cleared state must be visible before we
216 * test NEED_RESCHED:
217 */
218 smp_mb();
215 if (!need_resched()) 219 if (!need_resched())
216 safe_halt(); 220 safe_halt();
217 current_thread_info()->status |= TS_POLLING; 221 current_thread_info()->status |= TS_POLLING;
@@ -345,7 +349,11 @@ static void acpi_processor_idle(void)
345 */ 349 */
346 if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { 350 if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
347 current_thread_info()->status &= ~TS_POLLING; 351 current_thread_info()->status &= ~TS_POLLING;
348 smp_mb__after_clear_bit(); 352 /*
353 * TS_POLLING-cleared state must be visible before we
354 * test NEED_RESCHED:
355 */
356 smp_mb();
349 if (need_resched()) { 357 if (need_resched()) {
350 current_thread_info()->status |= TS_POLLING; 358 current_thread_info()->status |= TS_POLLING;
351 local_irq_enable(); 359 local_irq_enable();