The patch below does not apply to the 6.3-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.3.y git checkout FETCH_HEAD git cherry-pick -x 3bf8c6307bad5c0cc09cde982e146d847859b651 # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2023052834-enlighten-vacate-bfd6@gregkh' --subject-prefix 'PATCH 6.3.y' HEAD^..
Possible dependencies:
3bf8c6307bad ("cpufreq: amd-pstate: Update policy->cur in amd_pstate_adjust_perf()") 2dd6d0ebf740 ("cpufreq: amd-pstate: Add guided autonomous mode") 3e6e07805764 ("Documentation: cpufreq: amd-pstate: Move amd_pstate param to alphabetical order")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3bf8c6307bad5c0cc09cde982e146d847859b651 Mon Sep 17 00:00:00 2001 From: Wyes Karny wyes.karny@amd.com Date: Thu, 18 May 2023 05:58:19 +0000 Subject: [PATCH] cpufreq: amd-pstate: Update policy->cur in amd_pstate_adjust_perf()
Driver should update policy->cur after updating the frequency. Currently amd_pstate doesn't update policy->cur when `adjust_perf` is used. Which causes /proc/cpuinfo to show wrong cpu frequency. Fix this by updating policy->cur with correct frequency value in adjust_perf function callback.
- Before the fix: (setting min freq to 1.5 MHz)
[root@amd]# cat /proc/cpuinfo | grep "cpu MHz" | sort | uniq --count 1 cpu MHz : 1777.016 1 cpu MHz : 1797.160 1 cpu MHz : 1797.270 189 cpu MHz : 400.000
- After the fix: (setting min freq to 1.5 MHz)
[root@amd]# cat /proc/cpuinfo | grep "cpu MHz" | sort | uniq --count 1 cpu MHz : 1753.353 1 cpu MHz : 1756.838 1 cpu MHz : 1776.466 1 cpu MHz : 1776.873 1 cpu MHz : 1777.308 1 cpu MHz : 1779.900 183 cpu MHz : 1805.231 1 cpu MHz : 1956.815 1 cpu MHz : 2246.203 1 cpu MHz : 2259.984
Fixes: 1d215f0319c2 ("cpufreq: amd-pstate: Add fast switch function for AMD P-State") Signed-off-by: Wyes Karny wyes.karny@amd.com [ rjw: Subject edits ] Cc: 5.17+ stable@vger.kernel.org # 5.17+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index ac54779f5a49..ddd346a239e0 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -501,12 +501,14 @@ static void amd_pstate_adjust_perf(unsigned int cpu, unsigned long capacity) { unsigned long max_perf, min_perf, des_perf, - cap_perf, lowest_nonlinear_perf; + cap_perf, lowest_nonlinear_perf, max_freq; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); struct amd_cpudata *cpudata = policy->driver_data; + unsigned int target_freq;
cap_perf = READ_ONCE(cpudata->highest_perf); lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); + max_freq = READ_ONCE(cpudata->max_freq);
des_perf = cap_perf; if (target_perf < capacity) @@ -523,6 +525,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu, if (max_perf < min_perf) max_perf = min_perf;
+ des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); + target_freq = div_u64(des_perf * max_freq, max_perf); + policy->cur = target_freq; + amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true, policy->governor->flags); cpufreq_cpu_put(policy);
From: "Gautham R. Shenoy" gautham.shenoy@amd.com
[ Upstream commit 3bf8c6307bad5c0cc09cde982e146d847859b651 ]
Schedutil normally calls the adjust_perf callback for drivers with adjust_perf callback available and fast_switch_possible flag set. However, when frequency invariance is disabled and schedutil tries to invoke fast_switch. So, there is a chance of kernel crash if this function pointer is not set. To protect against this scenario add fast_switch callback to amd_pstate driver.
Fixes: 1d215f0319c2 ("cpufreq: amd-pstate: Add fast switch function for AMD P-State") Signed-off-by: Gautham R. Shenoy gautham.shenoy@amd.com Signed-off-by: Wyes Karny wyes.karny@amd.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com (cherry picked from commit 4badf2eb1e986bdbf34dd2f5d4c979553a86fe54) --- drivers/cpufreq/amd-pstate.c | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8dd46fad151e..7cce90d16b8d 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -422,9 +422,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) return 0; }
-static int amd_pstate_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) +static int amd_pstate_update_freq(struct cpufreq_policy *policy, + unsigned int target_freq, bool fast_switch) { struct cpufreq_freqs freqs; struct amd_cpudata *cpudata = policy->driver_data; @@ -443,14 +442,36 @@ static int amd_pstate_target(struct cpufreq_policy *policy, des_perf = DIV_ROUND_CLOSEST(target_freq * cap_perf, cpudata->max_freq);
- cpufreq_freq_transition_begin(policy, &freqs); - amd_pstate_update(cpudata, min_perf, des_perf, - max_perf, false); - cpufreq_freq_transition_end(policy, &freqs, false); + WARN_ON(fast_switch && !policy->fast_switch_enabled); + /* + * If fast_switch is desired, then there aren't any registered + * transition notifiers. See comment for + * cpufreq_enable_fast_switch(). + */ + if (!fast_switch) + cpufreq_freq_transition_begin(policy, &freqs); + + amd_pstate_update(cpudata, min_perf, des_perf, max_perf, fast_switch); + + if (!fast_switch) + cpufreq_freq_transition_end(policy, &freqs, false);
return 0; }
+static int amd_pstate_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + return amd_pstate_update_freq(policy, target_freq, false); +} + +static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + return amd_pstate_update_freq(policy, target_freq, true); +} + static void amd_pstate_adjust_perf(unsigned int cpu, unsigned long _min_perf, unsigned long target_perf, @@ -692,6 +713,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy)
freq_qos_remove_request(&cpudata->req[1]); freq_qos_remove_request(&cpudata->req[0]); + policy->fast_switch_possible = false; kfree(cpudata);
return 0; @@ -1226,6 +1248,7 @@ static struct cpufreq_driver amd_pstate_driver = { .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, .verify = amd_pstate_verify, .target = amd_pstate_target, + .fast_switch = amd_pstate_fast_switch, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, .suspend = amd_pstate_cpu_suspend,
On 30 May 11:16, Wyes Karny wrote:
From: "Gautham R. Shenoy" gautham.shenoy@amd.com
[ Upstream commit 3bf8c6307bad5c0cc09cde982e146d847859b651 ]
Schedutil normally calls the adjust_perf callback for drivers with adjust_perf callback available and fast_switch_possible flag set. However, when frequency invariance is disabled and schedutil tries to invoke fast_switch. So, there is a chance of kernel crash if this function pointer is not set. To protect against this scenario add fast_switch callback to amd_pstate driver.
Fixes: 1d215f0319c2 ("cpufreq: amd-pstate: Add fast switch function for AMD P-State") Signed-off-by: Gautham R. Shenoy gautham.shenoy@amd.com Signed-off-by: Wyes Karny wyes.karny@amd.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com (cherry picked from commit 4badf2eb1e986bdbf34dd2f5d4c979553a86fe54)
drivers/cpufreq/amd-pstate.c | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8dd46fad151e..7cce90d16b8d 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -422,9 +422,8 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) return 0; } -static int amd_pstate_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
+static int amd_pstate_update_freq(struct cpufreq_policy *policy,
unsigned int target_freq, bool fast_switch)
{ struct cpufreq_freqs freqs; struct amd_cpudata *cpudata = policy->driver_data; @@ -443,14 +442,36 @@ static int amd_pstate_target(struct cpufreq_policy *policy, des_perf = DIV_ROUND_CLOSEST(target_freq * cap_perf, cpudata->max_freq);
- cpufreq_freq_transition_begin(policy, &freqs);
- amd_pstate_update(cpudata, min_perf, des_perf,
max_perf, false);
- cpufreq_freq_transition_end(policy, &freqs, false);
- WARN_ON(fast_switch && !policy->fast_switch_enabled);
- /*
* If fast_switch is desired, then there aren't any registered
* transition notifiers. See comment for
* cpufreq_enable_fast_switch().
*/
- if (!fast_switch)
cpufreq_freq_transition_begin(policy, &freqs);
- amd_pstate_update(cpudata, min_perf, des_perf, max_perf, fast_switch);
- if (!fast_switch)
cpufreq_freq_transition_end(policy, &freqs, false);
return 0; } +static int amd_pstate_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
+{
- return amd_pstate_update_freq(policy, target_freq, false);
+}
+static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy,
unsigned int target_freq)
+{
- return amd_pstate_update_freq(policy, target_freq, true);
+}
static void amd_pstate_adjust_perf(unsigned int cpu, unsigned long _min_perf, unsigned long target_perf, @@ -692,6 +713,7 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) freq_qos_remove_request(&cpudata->req[1]); freq_qos_remove_request(&cpudata->req[0]);
- policy->fast_switch_possible = false; kfree(cpudata);
return 0; @@ -1226,6 +1248,7 @@ static struct cpufreq_driver amd_pstate_driver = { .flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, .verify = amd_pstate_verify, .target = amd_pstate_target,
- .fast_switch = amd_pstate_fast_switch, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, .suspend = amd_pstate_cpu_suspend,
Please ignore this. Wrong patch. Sorry for inconvenience.
Thanks, Wyes
-- 2.34.1
[ Upstream commit 3bf8c6307bad5c0cc09cde982e146d847859b651 ]
Driver should update policy->cur after updating the frequency. Currently amd_pstate doesn't update policy->cur when `adjust_perf` is used. Which causes /proc/cpuinfo to show wrong cpu frequency. Fix this by updating policy->cur with correct frequency value in adjust_perf function callback.
- Before the fix: (setting min freq to 1.5 MHz)
[root@amd]# cat /proc/cpuinfo | grep "cpu MHz" | sort | uniq --count 1 cpu MHz : 1777.016 1 cpu MHz : 1797.160 1 cpu MHz : 1797.270 189 cpu MHz : 400.000
- After the fix: (setting min freq to 1.5 MHz)
[root@amd]# cat /proc/cpuinfo | grep "cpu MHz" | sort | uniq --count 1 cpu MHz : 1753.353 1 cpu MHz : 1756.838 1 cpu MHz : 1776.466 1 cpu MHz : 1776.873 1 cpu MHz : 1777.308 1 cpu MHz : 1779.900 183 cpu MHz : 1805.231 1 cpu MHz : 1956.815 1 cpu MHz : 2246.203 1 cpu MHz : 2259.984
Fixes: 1d215f0319c2 ("cpufreq: amd-pstate: Add fast switch function for AMD P-State") Signed-off-by: Wyes Karny wyes.karny@amd.com [ rjw: Subject edits ] Cc: 5.17+ stable@vger.kernel.org # 5.17+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com (cherry picked from commit 3bf8c6307bad5c0cc09cde982e146d847859b651) --- drivers/cpufreq/amd-pstate.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 8dd46fad151e..497bde9cb213 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -457,12 +457,14 @@ static void amd_pstate_adjust_perf(unsigned int cpu, unsigned long capacity) { unsigned long max_perf, min_perf, des_perf, - cap_perf, lowest_nonlinear_perf; + cap_perf, lowest_nonlinear_perf, max_freq; struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); struct amd_cpudata *cpudata = policy->driver_data; + unsigned int target_freq;
cap_perf = READ_ONCE(cpudata->highest_perf); lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); + max_freq = READ_ONCE(cpudata->max_freq);
des_perf = cap_perf; if (target_perf < capacity) @@ -479,6 +481,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu, if (max_perf < min_perf) max_perf = min_perf;
+ des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); + target_freq = div_u64(des_perf * max_freq, max_perf); + policy->cur = target_freq; + amd_pstate_update(cpudata, min_perf, des_perf, max_perf, true); cpufreq_cpu_put(policy); }
linux-stable-mirror@lists.linaro.org