Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp2946755imm; Thu, 24 May 2018 19:39:24 -0700 (PDT) X-Google-Smtp-Source: AB8JxZodLyVkaqtgBCXfsjPFVCnFXqoHm4cWCs/5PfM7iXLcC/S5v0UV62zOpOKWZ8kSBhjob7U2 X-Received: by 2002:a63:710b:: with SMTP id m11-v6mr465089pgc.326.1527215964322; Thu, 24 May 2018 19:39:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527215964; cv=none; d=google.com; s=arc-20160816; b=usWYYYmG+rrnF5cPP3TyW1g6PhOKyx3aLXAOIL6X2mS9jTuvVSIlzTpvSJCr6DiMpL xEcnW//PewvcJdBDEdfD3cz2iUAlERJ4zJ+CfYosspbMaGASIMfFxQ52K4kTX2xMNWEH a5pJBRDuMFoHTchOlwKuq2YKSbb1QjlCVdOgHiNS9FmHD03dND0odQyUx6GY2Lk/ZsyJ su9/COWmHJQ0omNo55PcJw6fw8eZHha2s1ScK5UuZsyLXmGg8eK1Uj9aFRsWZMIkZxLC xCbgZjudmPtfgSgPE5lulu5JjzPjKLwlf5NbYTSVDvQTpvRKUp7LwJ5y7FTp7HBVFMAf /Vng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dmarc-filter :dkim-signature:dkim-signature:arc-authentication-results; bh=fetlTogsj3ekrJpREgsHtP6WDAnv1f5wLutfoXO3huc=; b=OYH4zOiU1dAaE5Zinp8T2BBp9FiX+Mu/Ury2v4i17ZVTktS4F5LC2KxMB1UFh3vRVH pZR2nZHVR1946ubwavJmlI+oEt8NHR8b/aUcYq3U8gU6AsWlln7dmDuNbuTqG4JDkfmo T21OUzyLpC7G0cQD884e9nOGKm1wdYLN+QlxHN98eEpHysYRHrDJOxxIn0tWJjj406KV M6Amn5h9U8btmAXf70EtcQbihaBN7ZE8/TvzufQMVL5kqbxweww7g4VlV4cK+Me1PAEs ERhqFxJcyS1amlyYGx6XZzmh4Nac4mPQ5ymOejIDhDyYjqYfLaCXs+z88O2zUFdosw2g mdIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=miBK31BC; dkim=pass header.i=@codeaurora.org header.s=default header.b=iy+PDeaN; 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 q19-v6si13092209pgc.524.2018.05.24.19.39.09; Thu, 24 May 2018 19:39:24 -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; dkim=pass header.i=@codeaurora.org header.s=default header.b=miBK31BC; dkim=pass header.i=@codeaurora.org header.s=default header.b=iy+PDeaN; 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 S971101AbeEXTZq (ORCPT + 99 others); Thu, 24 May 2018 15:25:46 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:47156 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S967823AbeEXTZl (ORCPT ); Thu, 24 May 2018 15:25:41 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 6C4E560B23; Thu, 24 May 2018 19:25:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1527189941; bh=Uxgi4lhBgAL5MqYBkq9D9xh+MItrr+WYDvNTTnZmnVA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=miBK31BC7fFYwjDgl/GRQIPad6emR/v70rIQUHwG3eFbZZzEe3ng6SUHyB2b4oRf2 vgQNEuiA3LUopV14CR23H+8F6rDBI7/H9TthOv9wGObpCXYuCovHseae/OJlG5xInq 5/+LcaVGTXH00FxI0FCju5YOisHPj5+4zR9HCw3Q= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from [10.226.58.143] (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: pprakash@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 396C3602BC; Thu, 24 May 2018 19:25:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1527189940; bh=Uxgi4lhBgAL5MqYBkq9D9xh+MItrr+WYDvNTTnZmnVA=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From; b=iy+PDeaN8y66Quhq+6UGEPSPPzB8uLdIts6HkMLItLWh3vv8Z4AqrWFmZ52RwxzBz xP6ukBJPSS3fyLrpHi0/4crap7pjDXULc26BSMTxVHNNu/G/h5WYW+MvE58PSXGRhT Baa6RtAiUi6hVzaJJHFFo1/cPpEzcOJiuUJ6i5Yk= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 396C3602BC Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=pprakash@codeaurora.org Subject: Re: [PATCH] cpufreq / CPPC: Add cpuinfo_cur_freq support for CPPC To: George Cherian , linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, viresh.kumar@linaro.org References: <1526989324-4183-1-git-send-email-george.cherian@cavium.com> From: "Prakash, Prashanth" Message-ID: Date: Thu, 24 May 2018 13:25:39 -0600 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: <1526989324-4183-1-git-send-email-george.cherian@cavium.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi George, On 5/22/2018 5:42 AM, George Cherian wrote: > Per Section 8.4.7.1.3 of ACPI 6.2, The platform provides performance > feedback via set of performance counters. To determine the actual > performance level delivered over time, OSPM may read a set of > performance counters from the Reference Performance Counter Register > and the Delivered Performance Counter Register. > > OSPM calculates the delivered performance over a given time period by > taking a beginning and ending snapshot of both the reference and > delivered performance counters, and calculating: > > delivered_perf = reference_perf X (delta of delivered_perf counter / delta of reference_perf counter). > > Implement the above and hook this to the cpufreq->get method. > > Signed-off-by: George Cherian > --- > drivers/cpufreq/cppc_cpufreq.c | 44 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c > index b15115a..a046915 100644 > --- a/drivers/cpufreq/cppc_cpufreq.c > +++ b/drivers/cpufreq/cppc_cpufreq.c > @@ -240,10 +240,54 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) > return ret; > } > > +static int cppc_get_rate_from_fbctrs(struct cppc_perf_fb_ctrs fb_ctrs_t0, > + struct cppc_perf_fb_ctrs fb_ctrs_t1) > +{ > + u64 delta_reference, delta_delivered; > + u64 reference_perf, ratio; > + > + reference_perf = fb_ctrs_t0.reference_perf; > + if (fb_ctrs_t1.reference > fb_ctrs_t0.reference) > + delta_reference = fb_ctrs_t1.reference - fb_ctrs_t0.reference; > + else /* Counters would have wrapped-around */ > + delta_reference = ((u64)(~((u64)0)) - fb_ctrs_t0.reference) + > + fb_ctrs_t1.reference; > + > + if (fb_ctrs_t1.delivered > fb_ctrs_t0.delivered) > + delta_delivered = fb_ctrs_t1.delivered - fb_ctrs_t0.delivered; > + else /* Counters would have wrapped-around */ > + delta_delivered = ((u64)(~((u64)0)) - fb_ctrs_t0.delivered) + > + fb_ctrs_t1.delivered; We need to check that the wraparound time is long enough to make sure that the counters cannot wrap around more than once. We can register a  get() api only after checking that wraparound time value is reasonably high. I am not aware of any platforms where wraparound time is soo short, but wouldn't hurt to check once during init. > + > + if (delta_reference) /* Check to avoid divide-by zero */ > + ratio = (delta_delivered * 1000) / delta_reference; Why not just return the computed value here instead of *1000 and later /1000? return (ref_per * delta_del) / delta_ref; > + else > + return -EINVAL; Instead of EINVAL, i think we should return current frequency. The counters can pause if CPUs are in idle state during our sampling interval, so If the counters did not progress, it is reasonable to assume the delivered perf was equal to desired perf. Even if platform wanted to limit, since the CPUs were asleep(idle) we could not have observed lower performance, so we will not throw off  any logic that could be driven using the returned value. > + > + return (reference_perf * ratio) / 1000; This should be converted to KHz as cpufreq is not aware of CPPC abstract scale > +} > + > +static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum) > +{ > + struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0}; > + int ret; > + > + ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t0); > + if (ret) > + return ret; > + > + ret = cppc_get_perf_ctrs(cpunum, &fb_ctrs_t1); > + if (ret) > + return ret; > + > + return cppc_get_rate_from_fbctrs(fb_ctrs_t0, fb_ctrs_t1); > +} We need to make sure that we get a reasonably sample so make sure the reported performance is accurate. The counters can capture short transient throttling/limiting, so by sampling a really short duration of time we could return quite inaccurate measure of performance. We need to include some reasonable delay between the two calls. What is reasonable is debatable - so this can be few(2-10) microseconds defined as default. If the same value doesn't work for all the platforms, we might need to add a platform specific value. > + > static struct cpufreq_driver cppc_cpufreq_driver = { > .flags = CPUFREQ_CONST_LOOPS, > .verify = cppc_verify_policy, > .target = cppc_cpufreq_set_target, > + .get = cppc_cpufreq_get_rate, > .init = cppc_cpufreq_cpu_init, > .stop_cpu = cppc_cpufreq_stop_cpu, > .name = "cppc_cpufreq",