From patchwork Fri Jun 9 10:15:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 103453 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp134374qgd; Fri, 9 Jun 2017 03:16:28 -0700 (PDT) X-Received: by 10.101.86.76 with SMTP id m12mr25885575pgs.137.1497003387909; Fri, 09 Jun 2017 03:16:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497003387; cv=none; d=google.com; s=arc-20160816; b=R64yHG1qH5vimrxHVym3ULZPSESnzcfsunS2tfiJN6Xqr0XGZHMkbHNghuuSbH6sAT Zi5xl8XbjJ00GUBpUp11sPYkZffISiLjyLbb1tL6H0wzFoPN/pHM+5N1OnTqL5Q05fEf VGMwGLBm8LUvEj1vSzMpeRKs7jhs3Pqwvo/b7ZURlbkPvQueKfhkfxTHKynrhVBTjJ73 fn45w5qiG2Kt0K3Pb4zp60GlmAnPEwfQD/uyHtnb3bRG9EBGPliXhX1PlBtzfu1BDWT7 eE2cuwxOZJ2zMPbrA0tAD3+kRDKhVbHQcw0rPogThKf7ahc3gjIkuGHy3Zcv4+nZZ4+Z SDvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=zJ0N2O4J6DgIjm3l24qgSQ1xQOvhx0TlCPXprKoc3OU=; b=DKh5eWgnljT4Erixj3wld95YCf1d9PM+vqJ7Er4GYFRXVJD5vbudYOBQ8xXtjTcZvw Y9zsWeNEPGlDy/GVvgay4iiCld/zhbKZlGljTk4qieaPTKqhGsDTafNbjMCE9/8i1HjA God7142mfyJdicPs7gEAzwW4/FelwnIaJTg470pP0h/2r/wnj7DPLZd2lhVCnPk+1+PX MD/WWbMqsUpAd4DzyP5BUyk3zPIrXOa6mVekFtU44LGNbeqLNJfK6Ajap5SX9EG4t4bs erLhhy9v0DBKtR7zMPe4uWFkw1RHcSbgtTStXejWoJ8u/U3qRr7WYloDilCPgTJDZskf zJUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a81si629412pfl.237.2017.06.09.03.16.27; Fri, 09 Jun 2017 03:16:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751645AbdFIKQT (ORCPT + 14 others); Fri, 9 Jun 2017 06:16:19 -0400 Received: from mail-pg0-f42.google.com ([74.125.83.42]:34863 "EHLO mail-pg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751637AbdFIKQR (ORCPT ); Fri, 9 Jun 2017 06:16:17 -0400 Received: by mail-pg0-f42.google.com with SMTP id k71so25273711pgd.2 for ; Fri, 09 Jun 2017 03:16:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=zJ0N2O4J6DgIjm3l24qgSQ1xQOvhx0TlCPXprKoc3OU=; b=TaDMUggTZQmqs9LmpPm4lVWOe8sSCiMfHj1xpp7EYUxOUSPOR7a43jYniSiKTqlmhe KLlZodw2ExfAI+exe+hxAit801O8udS19/T8Op1k6KCqm1DviqEVIz48hiAvW615pZfN rj66GEz8DNvof+vMY88NBNhtIMmXhesm1Ubi4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=zJ0N2O4J6DgIjm3l24qgSQ1xQOvhx0TlCPXprKoc3OU=; b=J5AlfoTg3XX7BKYwYfSx5ca72RIetxt+DAhw2w4MZmJfZSDB3UKW5DI5IPvzdvqG7X uM4RdyVfe9FGHZKO2CjwUK0bFU47/PI9Lhaww0Dcyeu0Q3V0EjnQtWj+TQxOovS4i156 ERLKlAvUTJ0CT3/2INCq8Ob/0l6ocfiS6o2X9W1N7IFHcVqX8Q45ZSWsuj9XBFGV5vks gD7moL/V6ypkxqw4qdOxQtDb0RIrpsuYu+AC8NkRIaZbfQO8zQfUlTsNW7y0UP8Lblgy CxwpKBvCUprajbJky4bAGV1D+D53/qNZiu6Zm8VWiwNi0frzcph7tlUc/tpVbxYiCGK+ jN5Q== X-Gm-Message-State: AODbwcDJLi8Vb4PWfV7zBJ90bUE3fKUB1w6yGYAi99WEXJD2R67z3GsE 6jHOJrTklxMGSel/ X-Received: by 10.84.175.129 with SMTP id t1mr30600832plb.159.1497003371782; Fri, 09 Jun 2017 03:16:11 -0700 (PDT) Received: from localhost ([122.172.91.138]) by smtp.gmail.com with ESMTPSA id 15sm2096126pfk.115.2017.06.09.03.16.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Jun 2017 03:16:11 -0700 (PDT) From: Viresh Kumar To: Rafael Wysocki , Ingo Molnar , Peter Zijlstra Cc: Viresh Kumar , linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Juri Lelli , patrick.bellasi@arm.com, john.ettedgui@gmail.com, Srinivas Pandruvada , Joel Fernandes , Morten Rasmussen Subject: [PATCH 2/3] cpufreq: schedutil: Fix selection algorithm while reducing frequency Date: Fri, 9 Jun 2017 15:45:55 +0530 Message-Id: <8d5e793df4f06d54794a889543817cf5be131650.1497002895.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.13.0.70.g6367777092d9 In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org While reducing frequency if there are no frequencies available between "current" and "next" calculated frequency, then the core will never select the "next" frequency. For example, consider the possible range of frequencies as 900 MHz, 1 GHz, 1.1 GHz, and 1.2 GHz. If the current frequency is 1.1 GHz and the next frequency (based on current utilization) is 1 GHz, then the schedutil governor will try to set the average of these as the next frequency (i.e. 1.05 GHz). Because we always try to find the lowest frequency greater than equal to the target frequency, cpufreq_driver_resolve_freq() will end up returning 1.1 GHz only. And we will not be able to reduce the frequency eventually. The worst hit is the policy->min frequency as that will never get selected after the frequency is increased once. This affects all the drivers that provide ->target() or ->target_index() callbacks. Though for cpufreq drivers, like intel_pstate, which provide ->target() but not ->resolve_freq() (i.e. cpufreq_driver_resolve_freq() simply returns the next frequency), sg_policy->next_freq gets updated with the average frequency. And so we will finally select the min frequency when the next_freq is 1 more than the min frequency as the average then will be equal to the min frequency. But that will also take lots of iterations of the schedutil update callbacks to happen. Fix that by not using the average value for the next_freq in such cases. Note that this still doesn't fix the drivers which provide ->target() but don't provide ->resolve_freq() (e.g. intel_pstate) and such drivers need to be updated to provide the ->resolve_freq() callbacks as well in order to fix this. Fixes: 39b64aa1c007 ("cpufreq: schedutil: Reduce frequencies slower") Signed-off-by: Viresh Kumar --- kernel/sched/cpufreq_schedutil.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) -- 2.13.0.70.g6367777092d9 diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 1852bd73d903..30e6a62d227c 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -117,6 +117,17 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, } } +static unsigned int resolve_freq(struct sugov_policy *sg_policy, + unsigned int freq) +{ + if (freq == sg_policy->cached_raw_freq && + sg_policy->next_freq != UINT_MAX) + return sg_policy->next_freq; + + sg_policy->cached_raw_freq = freq; + return cpufreq_driver_resolve_freq(sg_policy->policy, freq); +} + /** * get_next_freq - Compute a new frequency for a given cpufreq policy. * @sg_policy: schedutil policy object to compute the new frequency for. @@ -145,6 +156,7 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, struct cpufreq_policy *policy = sg_policy->policy; unsigned int freq = arch_scale_freq_invariant() ? policy->cpuinfo.max_freq : policy->cur; + unsigned int target, original = 0; freq = (freq + (freq >> 2)) * util / max; @@ -156,13 +168,24 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, if (freq < policy->min) freq = policy->min; - if (sg_policy->next_freq > freq) + if (sg_policy->next_freq > freq) { + original = freq; freq = (sg_policy->next_freq + freq) >> 1; + } - if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX) - return sg_policy->next_freq; - sg_policy->cached_raw_freq = freq; - return cpufreq_driver_resolve_freq(policy, freq); + target = resolve_freq(sg_policy, freq); + + /* + * While reducing frequency if there are no frequencies available + * between "original" and "next_freq", resolve_freq() will return + * next_freq because we always try to find the lowest frequency greater + * than equal to the "freq". Fix that by going directly to the + * "original" frequency in that case. + */ + if (unlikely(original && target == sg_policy->next_freq)) + target = resolve_freq(sg_policy, original); + + return target; } static void sugov_get_util(unsigned long *util, unsigned long *max)