From patchwork Thu Apr 28 18:00:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sai X-Patchwork-Id: 8974141 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2E39D9F39D for ; Thu, 28 Apr 2016 18:02:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 300B1202F0 for ; Thu, 28 Apr 2016 18:02:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F2524202DD for ; Thu, 28 Apr 2016 18:02:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752367AbcD1SCD (ORCPT ); Thu, 28 Apr 2016 14:02:03 -0400 Received: from hqemgate16.nvidia.com ([216.228.121.65]:17669 "EHLO hqemgate16.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751907AbcD1SCD (ORCPT ); Thu, 28 Apr 2016 14:02:03 -0400 Received: from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by hqemgate16.nvidia.com id ; Thu, 28 Apr 2016 11:01:58 -0700 Received: from HQMAIL101.nvidia.com ([172.20.187.10]) by hqnvupgp08.nvidia.com (PGP Universal service); Thu, 28 Apr 2016 11:01:36 -0700 X-PGP-Universal: processed; by hqnvupgp08.nvidia.com on Thu, 28 Apr 2016 11:01:36 -0700 Received: from [172.17.187.121] (172.17.187.121) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1130.7; Thu, 28 Apr 2016 18:02:01 +0000 Message-ID: <57224FA2.2080000@nvidia.com> Date: Thu, 28 Apr 2016 11:00:02 -0700 From: Sai Gurrappadi User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: , CC: , Subject: [RFC/PATCH] cpufreq: Fix GOV_LIMITS handling for the userspace governor X-Originating-IP: [172.17.187.121] X-ClientProxiedBy: HQMAIL106.nvidia.com (172.18.146.12) To HQMAIL101.nvidia.com (172.20.187.10) Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, the userspace governor only updates frequency on GOV_LIMITS if policy->cur falls outside policy->{min/max}. However, it is also necessary to update current frequency on GOV_LIMITS to match the user requested value if it can be achieved within the new policy->{max/min}. This was previously the behaviour in the governor until commit d1922f0 ("cpufreq: Simplify userspace governor") which incorrectly assumed that policy->cur == user requested frequency via scaling_setspeed. This won't be true if the user requested frequency falls outside policy->{min/max}. Ex: a temporary thermal cap throttled the user requested frequency. Fix this by doing a partial revert of commit d1922f0 to bring back the per-cpu cpu_set_freq variable that stores the user requested frequency. The governor will then try to achieve this request on every GOV_LIMITS. Signed-off-by: Sai Gurrappadi --- drivers/cpufreq/cpufreq_userspace.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) mutex_unlock(&userspace_mutex); @@ -62,6 +66,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, mutex_lock(&userspace_mutex); per_cpu(cpu_is_managed, cpu) = 1; + per_cpu(cpu_set_freq, cpu) = policy->cur; mutex_unlock(&userspace_mutex); break; case CPUFREQ_GOV_STOP: @@ -69,20 +74,27 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, mutex_lock(&userspace_mutex); per_cpu(cpu_is_managed, cpu) = 0; + per_cpu(cpu_set_freq, cpu) = 0; mutex_unlock(&userspace_mutex); break; case CPUFREQ_GOV_LIMITS: mutex_lock(&userspace_mutex); - pr_debug("limit event for cpu %u: %u - %u kHz, currently %u kHz\n", + pr_debug("limit event for cpu %u: %u - %u kHz, " + "currently %u kHz, last set to %u kHz\n", cpu, policy->min, policy->max, - policy->cur); + policy->cur, per_cpu(cpu_set_freq, cpu)); - if (policy->max < policy->cur) + if (policy->max < per_cpu(cpu_set_freq, cpu)) { __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - else if (policy->min > policy->cur) + } else if (policy->min > per_cpu(cpu_set_freq, cpu)) { __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L); + } else { + __cpufreq_driver_target(policy, + per_cpu(cpu_set_freq, cpu), + CPUFREQ_RELATION_L); + } mutex_unlock(&userspace_mutex); break; } diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 4d16f45..ae03ba7 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -18,6 +18,8 @@ #include #include +static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by + userspace */ static DEFINE_PER_CPU(unsigned int, cpu_is_managed); static DEFINE_MUTEX(userspace_mutex); @@ -38,6 +40,8 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) if (!per_cpu(cpu_is_managed, policy->cpu)) goto err; + per_cpu(cpu_set_freq, policy->cpu) = freq; + ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); err: