From: Ionela Voinescu <ionela.voinescu@arm.com>
To: Jie Zhan <zhanjie9@hisilicon.com>
Cc: beata.michalska@arm.com, wangxiongfeng2@huawei.com,
viresh.kumar@linaro.org, rafael@kernel.org,
linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linuxarm@huawei.com,
jonathan.cameron@huawei.com, wanghuiqiang@huawei.com,
zhenglifeng1@huawei.com, lihuisong@huawei.com,
yangyicong@huawei.com, liaochang1@huawei.com,
zengheng4@huawei.com
Subject: Re: [PATCH v2 1/3] cppc_cpufreq: Return desired perf in ->get() if feedback counters are 0
Date: Tue, 17 Sep 2024 11:36:37 +0100 [thread overview]
Message-ID: <ZulbtT8joKPXlFCL@arm.com> (raw)
In-Reply-To: <79353a26-7304-9d6a-9237-cfa8e7794601@hisilicon.com>
Hi,
On Friday 13 Sep 2024 at 20:05:50 (+0800), Jie Zhan wrote:
>
> Hi Ionela,
>
> On 12/09/2024 17:43, Ionela Voinescu wrote:
>
> ...
>
> >
> > A possible (slimmer) alternative implementation for you to consider
> > (this merges patches 1 & 2):
> >
> > diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> > index bafa32dd375d..c16be9651a6f 100644
> > --- a/drivers/cpufreq/cppc_cpufreq.c
> > +++ b/drivers/cpufreq/cppc_cpufreq.c
> > @@ -118,6 +118,9 @@ static void cppc_scale_freq_workfn(struct kthread_work *work)
> >
> > perf = cppc_perf_from_fbctrs(cpu_data, &cppc_fi->prev_perf_fb_ctrs,
> > &fb_ctrs);
> > + if (!perf)
> > + perf = cpu_data->perf_ctrls.desired_perf;
> > +
>
> I think it's better to just return here.
> If feedback counters are successfully read but unchanged, the following
> calculation and update in cppc_scale_freq_workfn() is meaningless because it
> won't change anything.
Agreed!
>
> > cppc_fi->prev_perf_fb_ctrs = fb_ctrs;
> >
> > perf <<= SCHED_CAPACITY_SHIFT;
> > @@ -726,7 +729,7 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data,
> >
> > /* Check to avoid divide-by zero and invalid delivered_perf */
> > if (!delta_reference || !delta_delivered)
> > - return cpu_data->perf_ctrls.desired_perf;
> > + return 0;
>
> This makes sense to me.
> Here is probably why Patch 2 looks bulky.
>
> >
> > return (reference_perf * delta_delivered) / delta_reference;
> > }
> > @@ -736,7 +739,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
> > struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0};
> > struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
> > struct cppc_cpudata *cpu_data;
> > - u64 delivered_perf;
> > + u64 delivered_perf = 0;
> > int ret;
> >
> > if (!policy)
> > @@ -747,19 +750,22 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
> > cpufreq_cpu_put(policy);
> >
> > ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0);
> > - if (ret)
> > - return 0;
> > -
> > - udelay(2); /* 2usec delay between sampling */
> > -
> > - ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
> > - if (ret)
> > - return 0;
> > + if (!ret) {
> > + udelay(2); /* 2usec delay between sampling */
> > + ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
> > + }
> > + if (!ret)
> > + delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0,
> > + &fb_ctrs_t1);
>
> TBH, 'if (!ret)' style looks very strange to me.
> We haven't done so anywhere in cppc_cpufreq, so let's keep consistency and make
> it easier for people to read and maintain?
I agree it's a bit of a difficult read, that's why I only sent my code
as a suggestion. I did like the benefit of not having to have two
different calls to cppc_perf_to_khz() and making the code below common
for the error and non-error paths. But it's up to you.
>
> > + if ((ret == -EFAULT) || !delivered_perf) {
> > + if (cppc_get_desired_perf(cpu, &delivered_perf))
> > + delivered_perf = cpu_data->perf_ctrls.desired_perf;
>
> will take this.
>
> > + }
> >
> > - delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0,
> > - &fb_ctrs_t1);
> > + if (delivered_perf)
> > + return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
> >
> > - return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
> > + return 0;
> > }
> >
> > disclaimer: not fully checked so likely not "production ready" code :)
> >
> > Hope it helps,
> > Ionela.
> >
> >>
> >> static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
> >> --
> >> 2.33.0
> >>
> >
>
> How about this? merged patch 1 & 2 as well.
>
> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> index bafa32dd375d..411303f2e8cb 100644
> --- a/drivers/cpufreq/cppc_cpufreq.c
> +++ b/drivers/cpufreq/cppc_cpufreq.c
> @@ -118,6 +118,9 @@ static void cppc_scale_freq_workfn(struct kthread_work *work)
>
> perf = cppc_perf_from_fbctrs(cpu_data, &cppc_fi->prev_perf_fb_ctrs,
> &fb_ctrs);
> + if (!perf)
> + return;
> +
> cppc_fi->prev_perf_fb_ctrs = fb_ctrs;
>
> perf <<= SCHED_CAPACITY_SHIFT;
> @@ -726,7 +729,7 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data,
>
> /* Check to avoid divide-by zero and invalid delivered_perf */
> if (!delta_reference || !delta_delivered)
> - return cpu_data->perf_ctrls.desired_perf;
> + return 0;
>
> return (reference_perf * delta_delivered) / delta_reference;
> }
> @@ -748,18 +751,32 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
>
> ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0);
> if (ret)
> - return 0;
> + goto out_err;
>
> udelay(2); /* 2usec delay between sampling */
>
> ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
> if (ret)
> - return 0;
> + goto out_err;
>
> delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0,
> &fb_ctrs_t1);
You need a check here for !delivered_perf (when at least one of the
deltas is 0) in which case it would be good to take the same error path
below. Something like:
if(delivered_perf)
return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
else
ret = -EFAULT;
That's why I did the tricky if/else dance above as we need to take the
error path below for multiple cases.
Thanks,
Ionela.
>
> return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
> +
> +out_err:
> + /*
> + * Feedback counters could be 0 when cores are powered down.
> + * Take desired perf for reflecting frequency in this case.
> + */
> + if (ret == -EFAULT) {
> + if (cppc_get_desired_perf(cpu, &delivered_perf))
> + delivered_perf = cpu_data->perf_ctrls.desired_perf;
> +
> + return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
> + }
> +
> + return 0;
> }
>
> static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
> ---
>
> Thanks indeed!
> Jie
next prev parent reply other threads:[~2024-09-17 10:36 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-12 7:22 [PATCH v2 0/3] cppc_cpufreq: Rework ->get() error handling when cores are idle Jie Zhan
2024-09-12 7:22 ` [PATCH v2 1/3] cppc_cpufreq: Return desired perf in ->get() if feedback counters are 0 Jie Zhan
2024-09-12 9:43 ` Ionela Voinescu
2024-09-13 12:05 ` Jie Zhan
2024-09-17 10:36 ` Ionela Voinescu [this message]
2024-09-18 2:05 ` Jie Zhan
2024-09-18 10:15 ` Ionela Voinescu
2024-09-19 1:17 ` Jie Zhan
2024-09-12 7:22 ` [PATCH v2 2/3] cppc_cpufreq: Return latest desired perf if feedback counters don't change Jie Zhan
2024-09-12 7:22 ` [PATCH v2 3/3] cppc_cpufreq: Remove HiSilicon CPPC workaround Jie Zhan
2024-09-14 12:13 ` kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2024-09-12 7:19 [PATCH v2 0/3] cppc_cpufreq: Rework ->get() error handling when cores are idle Jie Zhan
2024-09-12 7:19 ` [PATCH v2 1/3] cppc_cpufreq: Return desired perf in ->get() if feedback counters are 0 Jie Zhan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZulbtT8joKPXlFCL@arm.com \
--to=ionela.voinescu@arm.com \
--cc=beata.michalska@arm.com \
--cc=jonathan.cameron@huawei.com \
--cc=liaochang1@huawei.com \
--cc=lihuisong@huawei.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=rafael@kernel.org \
--cc=viresh.kumar@linaro.org \
--cc=wanghuiqiang@huawei.com \
--cc=wangxiongfeng2@huawei.com \
--cc=yangyicong@huawei.com \
--cc=zengheng4@huawei.com \
--cc=zhanjie9@hisilicon.com \
--cc=zhenglifeng1@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.