aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle/cpuidle-pseries.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-06-14 23:02:41 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2017-06-28 13:08:12 +1000
commit7ded429152e84831f6696585755f318fb351e67f (patch)
treefa7aa9cf3c30c61ef5ec7a01cbc92be38da99815 /drivers/cpuidle/cpuidle-pseries.c
parentcpuidle: powerpc: read mostly for common globals (diff)
downloadlinux-dev-7ded429152e84831f6696585755f318fb351e67f.tar.xz
linux-dev-7ded429152e84831f6696585755f318fb351e67f.zip
cpuidle: powerpc: no memory barrier after break from idle
A memory barrier is not required after the task wakes up, only if we clear the polling flag before waking. The case where we have work to do is the important one, so optimise for it. Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/cpuidle/cpuidle-pseries.c')
-rw-r--r--drivers/cpuidle/cpuidle-pseries.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
index a404f352d284..e9b3853d93ea 100644
--- a/drivers/cpuidle/cpuidle-pseries.c
+++ b/drivers/cpuidle/cpuidle-pseries.c
@@ -71,13 +71,20 @@ static int snooze_loop(struct cpuidle_device *dev,
while (!need_resched()) {
HMT_low();
HMT_very_low();
- if (snooze_timeout_en && get_tb() > snooze_exit_time)
+ if (likely(snooze_timeout_en) && get_tb() > snooze_exit_time) {
+ /*
+ * Task has not woken up but we are exiting the polling
+ * loop anyway. Require a barrier after polling is
+ * cleared to order subsequent test of need_resched().
+ */
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb();
break;
+ }
}
HMT_medium();
clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb();
idle_loop_epilog(in_purr);