Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp3803057imm; Mon, 15 Oct 2018 04:35:02 -0700 (PDT) X-Google-Smtp-Source: ACcGV61h8b/tydhPGZ+np1q/VqNnxsqlCsb5Kq5O0d+mu6rKvDLuWeyhT2+Y1REVyLy0mwmc/TmW X-Received: by 2002:a65:4301:: with SMTP id j1-v6mr15758782pgq.279.1539603302085; Mon, 15 Oct 2018 04:35:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539603302; cv=none; d=google.com; s=arc-20160816; b=0jjVYHI2DfCVPKXq/eVPLq5scXPuveFmAPvAPTgus0rw3rkbHPYT4eSeZ7ZJRwlTWa d0aZjlJdRchI4ixUVHcsahM6JykHvFTI6KrKs0XG7X1M/ZBBuWXj2dBr3JFZ+HfNTAFb 48MVp4+L9VGLKMmdWo76KRuJZIHXyTbopeDznavC5fGamsTYO876nHbPPlzuHWazA1pH 4+2stwzS/4MgtfrIHSOgFiGt7xBy/bwyY/I/X+suaCXtggF9OvoAFNWtcPQoyS4Fbj17 XdY4C3QJ+2B8iQlGxGyKL6Y+tXqDosxp8Utbpt4DgsEaQmnwwXSL1k8N3RuAwsl/sWzp 3ndA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=vJuTaZy5qdmeRJfoSISMnbbjcePNuM7r2fbUiewJv2o=; b=Gx0D37Auw2b716s9dfs8/iUUj9FcSCpX2pXxcq6ZkaUjd7Rp0QeUkA84Nc5GA2tumi NwhKG6KtTuxo1dnGdxkP00ShfT1qB1D9uUhyf2YMTqGcsdz5igDAVEPL8h8/vgd5U/MO uh1gDwQD1igF8MiBExAJJOD77g+S1t0lEq1J8jKWG4PyltHYaWEF7vq3/MrD86leG/Ix HMscFz0AkSfuxWG8TtRn9kwZtByQlYyuFpCfWQX5hTmDyCH1Z7UPHe3tyyFZgw6dmEc3 tBFsVXTDmkkcxzUt77POIK9/InldBDMKNPIPKb+9cmwLFvs4WynZDaq639QPtPis6QIp HyKQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 207-v6si9813759pgf.245.2018.10.15.04.34.47; Mon, 15 Oct 2018 04:35:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726595AbeJOTTL (ORCPT + 99 others); Mon, 15 Oct 2018 15:19:11 -0400 Received: from cloudserver094114.home.pl ([79.96.170.134]:60581 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726319AbeJOTTL (ORCPT ); Mon, 15 Oct 2018 15:19:11 -0400 Received: from 79.184.253.168.ipv4.supernova.orange.pl (79.184.253.168) (HELO aspire.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.83.148) id 2fde9848ee950d54; Mon, 15 Oct 2018 13:34:16 +0200 From: "Rafael J. Wysocki" To: Waldemar Rymarkiewicz Cc: Viresh Kumar , Waldemar Rymarkiewicz , linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, "Bartholomae, Thomas" Subject: Re: [PATCH] cpufreq: conservative: Fix requested_freq handling Date: Mon, 15 Oct 2018 13:31:03 +0200 Message-ID: <1926816.WaOCFmosuL@aspire.rjw.lan> In-Reply-To: References: <20181008150901.19667-1-waldemar.rymarkiewicz@gmail.com> <2671493.AgiGORq3CZ@aspire.rjw.lan> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Monday, October 15, 2018 11:34:33 AM CEST Waldemar Rymarkiewicz wrote: > On Thu, 11 Oct 2018 at 23:10, Rafael J. Wysocki wrote: > > > > On Tuesday, October 9, 2018 6:06:08 PM CEST Waldemar Rymarkiewicz wrote: > > > On Tue, 9 Oct 2018 at 09:47, Rafael J. Wysocki wrote: > > > > > > > > On Mon, Oct 8, 2018 at 5:11 PM Waldemar Rymarkiewicz > > > > wrote: > > > > > > > > > > From: Waldemar Rymarkiewicz > > > > > > > > > > The governor updates dbs_info->requested_freq only after increasing or > > > > > decreasing frequency. There is, however, an use case when this is not > > > > > sufficient. > > > > > > > > > > Imagine, external module constraining cpufreq policy in a way that policy->max > > > > > > > > Is the "external module" here a utility or a demon running in user space? > > > > > > No, this is a driver that communicates with a firmware and makes sure > > > CPU is running at the highest rate in specific time. > > > It uses verify_within_limits and update_policy, a standard way to > > > constraint cpufreq policy limits. > > > > > > > > @@ -136,10 +135,10 @@ static unsigned int cs_dbs_update(struct cpufreq_policy *policy) > > > > > requested_freq = policy->min; > > > > > > > > > > __cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L); > > > > > - dbs_info->requested_freq = requested_freq; > > > > > } > > > > > > > > > > out: > > > > > + dbs_info->requested_freq = requested_freq; > > > > > > > > This will have a side effect when requested_freq is updated before the > > > > thresholds checks due to the policy_dbs->idle_periods < UINT_MAX > > > > check. > > > > > > > > Shouldn't that be avoided? > > > > > > I would say we should. > > > > > > A hardware design I use is running 4.9 kernel where the check does not > > > exist yet, so there is not a problem. > > > Anyway, the check policy_dbs->idle_periods < UINT_MAX can change > > > requested_freq either to requested_freq = policy->min or > > > requested_freq -= freq_steps;. The first case will not change anything > > > for us as policy->max=min=cur. The second, however, will force to > > > update freq which is definitely not expected when limits are set to > > > min=max. Simply it will not go out here: > > > > > > if (load < cs_tuners->down_threshold) { > > > if (requested_freq == policy->min) > > > goto out; <--- > > > ... > > > } > > > > > > Am I right here? If so, shouldn't we check explicitly > > > > > > /* > > > * If requested_freq is out of range, it is likely that the limits > > > * changed in the meantime, so fall back to current frequency in that > > > * case. > > > */ > > > if (requested_freq > policy->max || requested_freq < policy->min) > > > requested_freq = policy->cur; > > > > > > +/* > > > +* If the the new limits min,max are equal, there is no point to process further > > > +*/ > > > + > > > +if (requested_freq == policy->max && requested_freq == policy->min) > > > + goto out; > > > > If my understanding of the problem is correct, it would be better to simply > > update dbs_info->requested_freq along with requested_freq when that is found > > to be out of range. IOW, something like the appended patch (untested). > > Yes, this will solve the original problem as well. > > I think there could also be a problem with policy_dbs->idle_periods < > UINT_MAX check. It it's true it can modify requested_freq ( > requested_freq -= freq_steps) and further it can result in a change of > the freq, requested_freq == policy->max is not anymore true. I would > expect governor not to change freq (requested_freq) when > policy->max=policy->min=policy->cur. Well, that's because there is a bug in that code IMO. It should never decrease requested_freq below policy->min in particular. Please find a patch with that fixed below. --- drivers/cpufreq/cpufreq_conservative.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: linux-pm/drivers/cpufreq/cpufreq_conservative.c =================================================================== --- linux-pm.orig/drivers/cpufreq/cpufreq_conservative.c +++ linux-pm/drivers/cpufreq/cpufreq_conservative.c @@ -80,8 +80,10 @@ static unsigned int cs_dbs_update(struct * changed in the meantime, so fall back to current frequency in that * case. */ - if (requested_freq > policy->max || requested_freq < policy->min) + if (requested_freq > policy->max || requested_freq < policy->min) { requested_freq = policy->cur; + dbs_info->requested_freq = requested_freq; + } freq_step = get_freq_step(cs_tuners, policy); @@ -92,7 +94,7 @@ static unsigned int cs_dbs_update(struct if (policy_dbs->idle_periods < UINT_MAX) { unsigned int freq_steps = policy_dbs->idle_periods * freq_step; - if (requested_freq > freq_steps) + if (requested_freq > policy->min + freq_steps) requested_freq -= freq_steps; else requested_freq = policy->min;