From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751469AbdJ1KAO (ORCPT ); Sat, 28 Oct 2017 06:00:14 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:56663 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750930AbdJ1KAI (ORCPT ); Sat, 28 Oct 2017 06:00:08 -0400 X-Google-Smtp-Source: ABhQp+TNsiaBsR5e/Dhz1r2g0vjcIPFfICen/6YqNTISSujK7RuV5tdwLYu3reEslsg7Y7f0qGExrQ== From: Joel Fernandes To: linux-kernel@vger.kernel.org Cc: Joel Fernandes , "Rafael J . Wysocki" , Viresh Kumar , Ingo Molnar , Peter Zijlstra , Frederic Weisbecker , Thomas Gleixner , "Cc: Srinivas Pandruvada" , "Cc: Len Brown" , "Cc: Juri Lelli" , "Cc: Patrick Bellasi" , "Cc: Steve Muckle" , "Cc: Brendan Jackman" , "Cc: Chris Redpath" , "Cc: Atish Patra" , "Cc: Dietmar Eggemann" , "Cc: Vincent Guittot" , "Cc: Morten Ramussen" , "Cc: EAS Dev" , "Cc: Android Kernel" Subject: [PATCH RFC 3/5] cpufreq: schedutil: Use idle_calls counter of the remote CPU Date: Sat, 28 Oct 2017 02:59:39 -0700 Message-Id: <20171028095941.4773-4-joelaf@google.com> X-Mailer: git-send-email 2.15.0.rc2.357.g7e34df9404-goog In-Reply-To: <20171028095941.4773-1-joelaf@google.com> References: <20171028095941.4773-1-joelaf@google.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since the recent remote cpufreq callback work, its possible that a cpufreq update is triggered from a remote CPU. For single policies however, the current code uses the local CPU when trying to determine if the remote sg_cpu entered idle or is busy. This is incorrect. To remedy this, compare with the nohz tick idle_calls counter of the remote CPU. Cc: Rafael J. Wysocki Cc: Viresh Kumar Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Thomas Gleixner Signed-off-by: Joel Fernandes --- include/linux/tick.h | 1 + kernel/sched/cpufreq_schedutil.c | 2 +- kernel/time/tick-sched.c | 13 +++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/linux/tick.h b/include/linux/tick.h index fe01e68bf520..31bf2ae3e9a7 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -118,6 +118,7 @@ extern void tick_nohz_idle_exit(void); extern void tick_nohz_irq_exit(void); extern ktime_t tick_nohz_get_sleep_length(void); extern unsigned long tick_nohz_get_idle_calls(void); +extern unsigned long tick_nohz_get_idle_calls_cpu(int cpu); extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time); #else /* !CONFIG_NO_HZ_COMMON */ diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 9209d83ecdcf..1383aa9efb4f 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -244,7 +244,7 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, #ifdef CONFIG_NO_HZ_COMMON static bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { - unsigned long idle_calls = tick_nohz_get_idle_calls(); + unsigned long idle_calls = tick_nohz_get_idle_calls_cpu(sg_cpu->cpu); bool ret = idle_calls == sg_cpu->saved_idle_calls; sg_cpu->saved_idle_calls = idle_calls; diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 7b258c59d78a..91d5e7be805b 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -1011,6 +1011,19 @@ ktime_t tick_nohz_get_sleep_length(void) return ts->sleep_length; } +/** + * tick_nohz_get_idle_calls_cpu - return the current idle calls counter value + * for a particular CPU. + * + * Called from the schedutil frequency scaling governor in scheduler context. + */ +unsigned long tick_nohz_get_idle_calls_cpu(int cpu) +{ + struct tick_sched *ts = tick_get_tick_sched(cpu); + + return ts->idle_calls; +} + /** * tick_nohz_get_idle_calls - return the current idle calls counter value * -- 2.15.0.rc2.357.g7e34df9404-goog