summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/amd-pstate.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index b357189f4f8e..25a179b89a74 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -699,9 +699,12 @@ static void amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
WRITE_ONCE(cpudata->max_limit_freq, policy->max);
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
+ u8 min_limit_perf = perf.bios_min_perf ?: perf.nominal_perf;
+ u32 min_limit_freq;
+
/*
- * For performance policy, set MinPerf to nominal_perf rather than
- * highest_perf or lowest_nonlinear_perf.
+ * For performance policy, set MinPerf to nominal_perf / bios_min_perf
+ * rather than highest_perf or lowest_nonlinear_perf.
*
* Per commit 0c411b39e4f4c, using highest_perf was observed
* to cause frequency throttling on power-limited platforms, leading to
@@ -709,11 +712,18 @@ static void amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
* performance too much for HPC workloads requiring high frequency
* operation and minimal wakeup latency from idle states.
*
- * nominal_perf therefore provides a balance by avoiding throttling
- * while still maintaining enough performance for HPC workloads.
+ * nominal_perf therefore provides a balanced default by avoiding
+ * throttling while still maintaining enough performance for HPC
+ * workloads when bios_min_perf is not available.
+ *
+ * When bios_min_perf is available, users have profiled their workloads
+ * to understand the best idling frequency. Use that instead.
*/
- perf.min_limit_perf = min(perf.nominal_perf, perf.max_limit_perf);
- WRITE_ONCE(cpudata->min_limit_freq, min(cpudata->nominal_freq, cpudata->max_limit_freq));
+ min_limit_perf = min(min_limit_perf, perf.max_limit_perf);
+ min_limit_freq = perf_to_freq(perf, cpudata->nominal_freq, min_limit_perf);
+ perf.min_limit_perf = min_limit_perf;
+
+ WRITE_ONCE(cpudata->min_limit_freq, min(min_limit_freq, cpudata->max_limit_freq));
} else {
perf.min_limit_perf = freq_to_perf(perf, cpudata->nominal_freq, policy->min);
WRITE_ONCE(cpudata->min_limit_freq, policy->min);