From: Viresh Kumar <viresh.kumar@linaro.org>
To: Ionela Voinescu <ionela.voinescu@arm.com>
Cc: rjw@rjwysocki.net, sudeep.holla@arm.com,
linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] cpufreq,cppc: fix issue when hotplugging out policy->cpu
Date: Fri, 4 Sep 2020 10:36:04 +0530 [thread overview]
Message-ID: <20200904050604.yoar2c6fofcikipp@vireshk-i7> (raw)
In-Reply-To: <20200903111955.31029-1-ionela.voinescu@arm.com>
On 03-09-20, 12:19, Ionela Voinescu wrote:
> An issue is observed in the cpufreq CPPC driver when having dependency
> domains (PSD) and the policy->cpu is hotplugged out.
>
> Considering a platform with 4 CPUs and 2 PSD domains (CPUs 0 and 1 in
> PSD-1, CPUs 2 and 3 in PSD-2), cppc_cpufreq_cpu_init() will be called
> for the two cpufreq policies that are created and it will set
> all_cpu_data[policy->cpu]->cpu = policy->cpu.
>
> Therefore all_cpu_data[0]->cpu=0, and all_cpu_data[2]->cpu=2. But for
> CPUs 1 and 3, all_cpu_data[{1,3}]->cpu will remain 0 from the structure
> allocation.
>
> If CPU 2 is hotplugged out, CPU 3 will become policy->cpu. But its
> all_cpu_data[3]->cpu will remain 0. Later, when the .target() function
> is called for policy2, the cpu argument to cppc_set_perf() will be 0 and
> therefore it will use the performance controls of CPU 0, which will
> result in a performance level change for the wrong domain.
>
> While the possibility of setting a correct CPU value in the per-cpu
> cppc_cpudata structure is available, it can be noticed that this cpu value
> is not used at all outside the .target() function, where it's not actually
> necessary. Therefore, remove the cpu variable from the cppc_cpudata
> structure and use policy->cpu in the .target() function as done for the
> other CPPC cpufreq functions.
>
> Fixes: 5477fb3bd1e8 ("ACPI / CPPC: Add a CPUFreq driver for use with CPPC")
> Signed-off-by: Ionela Voinescu <ionela.voinescu@arm.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>
> Testing was done on a Juno R2 platform (with the proper ACPI/CPPC setup):
> CPUs 0, 1, 2, 3 are in PSD-0 (policy0), CPUs 4 and 5 are in PSD-4
> (policy4).
>
> Before the fix:
>
> root@sqwt-ubuntu:~# dmesg | grep address
> [ 2.165177] ACPI CPPC: ACPI desired perf address 0: - ffff80001004d200
> [ 2.174226] ACPI CPPC: ACPI desired perf address 1: - ffff800010055200
> [ 2.183231] ACPI CPPC: ACPI desired perf address 2: - ffff80001005d200
> [ 2.192234] ACPI CPPC: ACPI desired perf address 3: - ffff800010065200
> [ 2.201245] ACPI CPPC: ACPI desired perf address 4: - ffff80001006d218
> [ 2.210256] ACPI CPPC: ACPI desired perf address 5: - ffff800011ff1218
> [..]
> [ 2.801940] ACPI CPPC: Writing to address for CPU 0:ffff80001004d200: 38300
> [ 2.835286] ACPI CPPC: Writing to address for CPU 4:ffff80001006d218: 102400
> [..]
> root@sqwt-ubuntu:~# cd /sys/devices/system/cpu/cpufreq/
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 600000 > policy4/scaling_setspeed
> [ 72.098758] ACPI CPPC: Writing to address for CPU 4:ffff80001006d218: 51200
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 1200000 > policy4/scaling_setspeed
> [ 85.430645] ACPI CPPC: Writing to address for CPU 4:ffff80001006d218: 102400
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 0 > ../cpu4/online
> [ 102.606380] CPPC Cpufreq:CPPC: Calculate: (6285/261)*4266=102727.
> [ 102.612491] CPPC Cpufreq:CPPC: Core rate = 1203832, arch timer rate: 50000000
> [ 102.619659] ACPI CPPC: Writing to address for CPU 0:ffff80001004d200: 102400
> [ 102.626898] CPU4: shutdown
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 600000 > policy4/scaling_setspeed
> [ 141.116882] ACPI CPPC: Writing to address for CPU 0:ffff80001004d200: 51200
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 1200000 > policy4/scaling_setspeed
> [ 159.288273] ACPI CPPC: Writing to address for CPU 0:ffff80001004d200: 102400
>
>
> After the fix:
>
> root@sqwt-ubuntu:~# cd /sys/devices/system/cpu/cpufreq/
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 600000 > policy4/scaling_setspeed
> [ 139.903322] ACPI CPPC: Writing to address for CPU 4:ffff80001006d218: 51200
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 1200000 > policy4/scaling_setspeed
> [ 147.279040] ACPI CPPC: Writing to address for CPU 4:ffff80001006d218: 102400
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 0 > ../cpu4/online
> [ 153.598686] CPPC Cpufreq:CPPC: Calculate: (6171/253)*4266=104053.
> [ 153.604797] CPPC Cpufreq:CPPC: Core rate = 1219371, arch timer rate: 50000000
> [ 153.611960] ACPI CPPC: Writing to address for CPU 5:ffff800011ff1218: 102400
> [ 153.619190] CPU4: shutdown
> [ 153.621911] psci: CPU4 killed (polled 0 ms)
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 600000 > policy4/scaling_setspeed
> [ 170.122495] ACPI CPPC: Writing to address for CPU 5:ffff800011ff1218: 51200
> root@sqwt-ubuntu:/sys/devices/system/cpu/cpufreq# echo 1200000 > policy4/scaling_setspeed
> [ 177.206342] ACPI CPPC: Writing to address for CPU 5:ffff800011ff1218: 102400
>
> Thanks,
> Ionela.
>
> drivers/cpufreq/cppc_cpufreq.c | 8 ++++----
> include/acpi/cppc_acpi.h | 1 -
> 2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
> index f29e8d0553a8..54457f5fe49e 100644
> --- a/drivers/cpufreq/cppc_cpufreq.c
> +++ b/drivers/cpufreq/cppc_cpufreq.c
> @@ -149,8 +149,9 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
> unsigned int target_freq,
> unsigned int relation)
> {
> - struct cppc_cpudata *cpu;
> struct cpufreq_freqs freqs;
> + int cpu_num = policy->cpu;
> + struct cppc_cpudata *cpu;
> u32 desired_perf;
> int ret = 0;
>
> @@ -166,12 +167,12 @@ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
> freqs.new = target_freq;
>
> cpufreq_freq_transition_begin(policy, &freqs);
> - ret = cppc_set_perf(cpu->cpu, &cpu->perf_ctrls);
> + ret = cppc_set_perf(cpu_num, &cpu->perf_ctrls);
> cpufreq_freq_transition_end(policy, &freqs, ret != 0);
>
> if (ret)
> pr_debug("Failed to set target on CPU:%d. ret:%d\n",
> - cpu->cpu, ret);
> + cpu_num, ret);
>
> return ret;
> }
> @@ -247,7 +248,6 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
>
> cpu = all_cpu_data[policy->cpu];
>
> - cpu->cpu = cpu_num;
> ret = cppc_get_perf_caps(policy->cpu, &cpu->perf_caps);
>
> if (ret) {
> diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
> index a6a9373ab863..451132ec83c9 100644
> --- a/include/acpi/cppc_acpi.h
> +++ b/include/acpi/cppc_acpi.h
> @@ -124,7 +124,6 @@ struct cppc_perf_fb_ctrs {
>
> /* Per CPU container for runtime CPPC management. */
> struct cppc_cpudata {
> - int cpu;
> struct cppc_perf_caps perf_caps;
> struct cppc_perf_ctrls perf_ctrls;
> struct cppc_perf_fb_ctrs perf_fb_ctrs;
With the way things are designed, I believe this is one of the bugs
out of many.
The structure cppc_cpudata must be shared across all CPUs of the same
policy, so they all end up using the same set of values for different
variables. i.e. it shouldn't be a per-cpu thing at all. Just allocate
it from cpufreq_driver->init and store in policy->driver_data for use
elsewhere.
That would be a proper fix IMO, we just avoided one of the bugs here
otherwise.
--
viresh
next prev parent reply other threads:[~2020-09-04 5:06 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-03 11:19 [PATCH] cpufreq,cppc: fix issue when hotplugging out policy->cpu Ionela Voinescu
2020-09-04 5:06 ` Viresh Kumar [this message]
2020-09-04 9:43 ` Ionela Voinescu
2020-09-07 6:11 ` Viresh Kumar
2020-09-22 16:25 ` Ionela Voinescu
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=20200904050604.yoar2c6fofcikipp@vireshk-i7 \
--to=viresh.kumar@linaro.org \
--cc=ionela.voinescu@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=sudeep.holla@arm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).