From patchwork Fri Sep 9 22:00:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Rafael J. Wysocki" X-Patchwork-Id: 9324497 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E6D9360869 for ; Fri, 9 Sep 2016 21:56:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CEDAF2A007 for ; Fri, 9 Sep 2016 21:56:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B43542A027; Fri, 9 Sep 2016 21:56:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 558312A023 for ; Fri, 9 Sep 2016 21:56:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754337AbcIIV4N (ORCPT ); Fri, 9 Sep 2016 17:56:13 -0400 Received: from cloudserver094114.home.net.pl ([79.96.170.134]:62328 "HELO cloudserver094114.home.net.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751989AbcIIV4L (ORCPT ); Fri, 9 Sep 2016 17:56:11 -0400 Received: from 217.96.255.47.ipv4.supernova.orange.pl (217.96.255.47) (HELO vostro.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer v0.80.3) id 061dc71e5a1ff605; Fri, 9 Sep 2016 23:56:09 +0200 From: "Rafael J. Wysocki" To: Linux PM list Cc: Linux Kernel Mailing List , Srinivas Pandruvada , Peter Zijlstra , Viresh Kumar , Ingo Molnar , Vincent Guittot , Morten Rasmussen , Juri Lelli , Dietmar Eggemann , Steve Muckle , Doug Smythies Subject: [Resend][PATCH 2/3] cpufreq: schedutil: Add iowait boosting Date: Sat, 10 Sep 2016 00:00:31 +0200 Message-ID: <1928525.UHD8eb6HiL@vostro.rjw.lan> User-Agent: KMail/4.11.5 (Linux/4.8.0-rc2+; KDE/4.11.5; x86_64; ; ) In-Reply-To: <21371892.ALJNnHKoBY@vostro.rjw.lan> References: <21371892.ALJNnHKoBY@vostro.rjw.lan> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Rafael J. Wysocki Modify the schedutil cpufreq governor to boost the CPU frequency if the SCHED_CPUFREQ_IOWAIT flag is passed to it via cpufreq_update_util(). If that happens, the frequency is set to the maximum during the first update after receiving the SCHED_CPUFREQ_IOWAIT flag and then the boost is reduced by half during each following update. Signed-off-by: Rafael J. Wysocki Looks-good-to: Steve Muckle Acked-by: Peter Zijlstra (Intel) --- kernel/sched/cpufreq_schedutil.c | 53 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-pm/kernel/sched/cpufreq_schedutil.c =================================================================== --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c +++ linux-pm/kernel/sched/cpufreq_schedutil.c @@ -47,11 +47,13 @@ struct sugov_cpu { struct sugov_policy *sg_policy; unsigned int cached_raw_freq; + unsigned long iowait_boost; + unsigned long iowait_boost_max; + u64 last_update; /* The fields below are only needed when sharing a policy. */ unsigned long util; unsigned long max; - u64 last_update; unsigned int flags; }; @@ -153,6 +155,36 @@ static void sugov_get_util(unsigned long *max = cfs_max; } +static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time, + unsigned int flags) +{ + if (flags & SCHED_CPUFREQ_IOWAIT) { + sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; + } else if (sg_cpu->iowait_boost) { + s64 delta_ns = time - sg_cpu->last_update; + + /* Clear iowait_boost if the CPU apprears to have been idle. */ + if (delta_ns > TICK_NSEC) + sg_cpu->iowait_boost = 0; + } +} + +static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, + unsigned long *max) +{ + unsigned long boost_util = sg_cpu->iowait_boost; + unsigned long boost_max = sg_cpu->iowait_boost_max; + + if (!boost_util) + return; + + if (*util * boost_max < *max * boost_util) { + *util = boost_util; + *max = boost_max; + } + sg_cpu->iowait_boost >>= 1; +} + static void sugov_update_single(struct update_util_data *hook, u64 time, unsigned int flags) { @@ -162,6 +194,9 @@ static void sugov_update_single(struct u unsigned long util, max; unsigned int next_f; + sugov_set_iowait_boost(sg_cpu, time, flags); + sg_cpu->last_update = time; + if (!sugov_should_update_freq(sg_policy, time)) return; @@ -169,6 +204,7 @@ static void sugov_update_single(struct u next_f = policy->cpuinfo.max_freq; } else { sugov_get_util(&util, &max); + sugov_iowait_boost(sg_cpu, &util, &max); next_f = get_next_freq(sg_cpu, util, max); } sugov_update_commit(sg_policy, time, next_f); @@ -187,6 +223,8 @@ static unsigned int sugov_next_freq_shar if (flags & SCHED_CPUFREQ_RT_DL) return max_f; + sugov_iowait_boost(sg_cpu, &util, &max); + for_each_cpu(j, policy->cpus) { struct sugov_cpu *j_sg_cpu; unsigned long j_util, j_max; @@ -201,12 +239,13 @@ static unsigned int sugov_next_freq_shar * frequency update and the time elapsed between the last update * of the CPU utilization and the last frequency update is long * enough, don't take the CPU into account as it probably is - * idle now. + * idle now (and clear iowait_boost for it). */ delta_ns = last_freq_update_time - j_sg_cpu->last_update; - if (delta_ns > TICK_NSEC) + if (delta_ns > TICK_NSEC) { + j_sg_cpu->iowait_boost = 0; continue; - + } if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL) return max_f; @@ -216,6 +255,8 @@ static unsigned int sugov_next_freq_shar util = j_util; max = j_max; } + + sugov_iowait_boost(j_sg_cpu, &util, &max); } return get_next_freq(sg_cpu, util, max); @@ -236,6 +277,8 @@ static void sugov_update_shared(struct u sg_cpu->util = util; sg_cpu->max = max; sg_cpu->flags = flags; + + sugov_set_iowait_boost(sg_cpu, time, flags); sg_cpu->last_update = time; if (sugov_should_update_freq(sg_policy, time)) { @@ -468,6 +511,8 @@ static int sugov_start(struct cpufreq_po sg_cpu->flags = SCHED_CPUFREQ_RT; sg_cpu->last_update = 0; sg_cpu->cached_raw_freq = 0; + sg_cpu->iowait_boost = 0; + sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util, sugov_update_shared); } else {