From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752584AbdFNNDV (ORCPT ); Wed, 14 Jun 2017 09:03:21 -0400 Received: from mail-pg0-f66.google.com ([74.125.83.66]:36422 "EHLO mail-pg0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752006AbdFNNDS (ORCPT ); Wed, 14 Jun 2017 09:03:18 -0400 From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Cc: Nicholas Piggin , Michael Ellerman , Vaidyanathan Srinivasan , "Gautham R . Shenoy" , "Rafael J . Wysocki" , Daniel Lezcano , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/3] cpuidle: powerpc: no memory barrier after break from idle Date: Wed, 14 Jun 2017 23:02:41 +1000 Message-Id: <20170614130241.19865-4-npiggin@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170614130241.19865-1-npiggin@gmail.com> References: <20170614130241.19865-1-npiggin@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Signed-off-by: Nicholas Piggin --- drivers/cpuidle/cpuidle-powernv.c | 11 +++++++++-- drivers/cpuidle/cpuidle-pseries.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index abf2ffcd4a0a..722b81b03593 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -59,14 +59,21 @@ static int snooze_loop(struct cpuidle_device *dev, ppc64_runlatch_off(); HMT_very_low(); while (!need_resched()) { - if (likely(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(); ppc64_runlatch_on(); clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb(); return index; } 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); -- 2.11.0