aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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
4 files changed, 24 insertions, 5 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.