229 lines
7.1 KiB
Diff
229 lines
7.1 KiB
Diff
From 649d296be0c7f0df6e71b4fca25fdbe75cb3994e Mon Sep 17 00:00:00 2001
|
|
From: Oleksandr Natalenko <oleksandr@natalenko.name>
|
|
Date: Thu, 17 Oct 2024 17:03:11 +0200
|
|
Subject: amd-pstate-6.11: update setting the minimum frequency to
|
|
lowest_nonlinear_freq patchset to v3
|
|
|
|
Signed-off-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
|
---
|
|
drivers/cpufreq/amd-pstate.c | 67 +++++++++++++++++++++---------------
|
|
drivers/cpufreq/amd-pstate.h | 4 +--
|
|
drivers/cpufreq/cpufreq.c | 6 +---
|
|
include/linux/cpufreq.h | 6 ----
|
|
4 files changed, 43 insertions(+), 40 deletions(-)
|
|
|
|
--- a/drivers/cpufreq/amd-pstate.c
|
|
+++ b/drivers/cpufreq/amd-pstate.c
|
|
@@ -557,9 +557,28 @@ cpufreq_policy_put:
|
|
cpufreq_cpu_put(policy);
|
|
}
|
|
|
|
-static int amd_pstate_verify(struct cpufreq_policy_data *policy)
|
|
+static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
|
|
{
|
|
- cpufreq_verify_within_cpu_limits(policy);
|
|
+ /*
|
|
+ * Initialize lower frequency limit (i.e.policy->min) with
|
|
+ * lowest_nonlinear_frequency which is the most energy efficient
|
|
+ * frequency. Override the initial value set by cpufreq core and
|
|
+ * amd-pstate qos_requests.
|
|
+ */
|
|
+ if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) {
|
|
+ struct cpufreq_policy *policy = cpufreq_cpu_get(policy_data->cpu);
|
|
+ struct amd_cpudata *cpudata;
|
|
+
|
|
+ if (!policy)
|
|
+ return -EINVAL;
|
|
+
|
|
+ cpudata = policy->driver_data;
|
|
+ policy_data->min = cpudata->lowest_nonlinear_freq;
|
|
+ cpufreq_cpu_put(policy);
|
|
+ }
|
|
+
|
|
+ cpufreq_verify_within_cpu_limits(policy_data);
|
|
+ pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min);
|
|
|
|
return 0;
|
|
}
|
|
@@ -709,7 +728,7 @@ static int amd_pstate_cpu_boost_update(s
|
|
policy->max = policy->cpuinfo.max_freq;
|
|
|
|
if (cppc_state == AMD_PSTATE_PASSIVE) {
|
|
- ret = freq_qos_update_request(&cpudata->max_freq_req, policy->cpuinfo.max_freq);
|
|
+ ret = freq_qos_update_request(&cpudata->req[1], policy->cpuinfo.max_freq);
|
|
if (ret < 0)
|
|
pr_debug("Failed to update freq constraint: CPU%d\n", cpudata->cpu);
|
|
}
|
|
@@ -976,17 +995,17 @@ static int amd_pstate_cpu_init(struct cp
|
|
|
|
ret = amd_pstate_init_perf(cpudata);
|
|
if (ret)
|
|
- goto free_cpudata;
|
|
+ goto free_cpudata1;
|
|
|
|
amd_pstate_init_prefcore(cpudata);
|
|
|
|
ret = amd_pstate_init_freq(cpudata);
|
|
if (ret)
|
|
- goto free_cpudata;
|
|
+ goto free_cpudata1;
|
|
|
|
ret = amd_pstate_init_boost_support(cpudata);
|
|
if (ret)
|
|
- goto free_cpudata;
|
|
+ goto free_cpudata1;
|
|
|
|
min_freq = READ_ONCE(cpudata->min_freq);
|
|
max_freq = READ_ONCE(cpudata->max_freq);
|
|
@@ -1008,11 +1027,18 @@ static int amd_pstate_cpu_init(struct cp
|
|
if (cpu_feature_enabled(X86_FEATURE_CPPC))
|
|
policy->fast_switch_possible = true;
|
|
|
|
- ret = freq_qos_add_request(&policy->constraints, &cpudata->max_freq_req,
|
|
+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
|
|
+ FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
|
|
+ goto free_cpudata1;
|
|
+ }
|
|
+
|
|
+ ret = freq_qos_add_request(&policy->constraints, &cpudata->req[1],
|
|
FREQ_QOS_MAX, policy->cpuinfo.max_freq);
|
|
if (ret < 0) {
|
|
dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret);
|
|
- goto free_cpudata;
|
|
+ goto free_cpudata2;
|
|
}
|
|
|
|
cpudata->max_limit_freq = max_freq;
|
|
@@ -1025,7 +1051,9 @@ static int amd_pstate_cpu_init(struct cp
|
|
|
|
return 0;
|
|
|
|
-free_cpudata:
|
|
+free_cpudata2:
|
|
+ freq_qos_remove_request(&cpudata->req[0]);
|
|
+free_cpudata1:
|
|
kfree(cpudata);
|
|
return ret;
|
|
}
|
|
@@ -1034,7 +1062,8 @@ static void amd_pstate_cpu_exit(struct c
|
|
{
|
|
struct amd_cpudata *cpudata = policy->driver_data;
|
|
|
|
- freq_qos_remove_request(&cpudata->max_freq_req);
|
|
+ freq_qos_remove_request(&cpudata->req[1]);
|
|
+ freq_qos_remove_request(&cpudata->req[0]);
|
|
policy->fast_switch_possible = false;
|
|
kfree(cpudata);
|
|
}
|
|
@@ -1658,13 +1687,6 @@ static int amd_pstate_epp_cpu_offline(st
|
|
return 0;
|
|
}
|
|
|
|
-static int amd_pstate_epp_verify_policy(struct cpufreq_policy_data *policy)
|
|
-{
|
|
- cpufreq_verify_within_cpu_limits(policy);
|
|
- pr_debug("policy_max =%d, policy_min=%d\n", policy->max, policy->min);
|
|
- return 0;
|
|
-}
|
|
-
|
|
static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
|
|
{
|
|
struct amd_cpudata *cpudata = policy->driver_data;
|
|
@@ -1703,13 +1725,6 @@ static int amd_pstate_epp_resume(struct
|
|
return 0;
|
|
}
|
|
|
|
-static int amd_pstate_get_init_min_freq(struct cpufreq_policy *policy)
|
|
-{
|
|
- struct amd_cpudata *cpudata = policy->driver_data;
|
|
-
|
|
- return READ_ONCE(cpudata->lowest_nonlinear_freq);
|
|
-}
|
|
-
|
|
static struct cpufreq_driver amd_pstate_driver = {
|
|
.flags = CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS,
|
|
.verify = amd_pstate_verify,
|
|
@@ -1723,12 +1738,11 @@ static struct cpufreq_driver amd_pstate_
|
|
.update_limits = amd_pstate_update_limits,
|
|
.name = "amd-pstate",
|
|
.attr = amd_pstate_attr,
|
|
- .get_init_min_freq = amd_pstate_get_init_min_freq,
|
|
};
|
|
|
|
static struct cpufreq_driver amd_pstate_epp_driver = {
|
|
.flags = CPUFREQ_CONST_LOOPS,
|
|
- .verify = amd_pstate_epp_verify_policy,
|
|
+ .verify = amd_pstate_verify,
|
|
.setpolicy = amd_pstate_epp_set_policy,
|
|
.init = amd_pstate_epp_cpu_init,
|
|
.exit = amd_pstate_epp_cpu_exit,
|
|
@@ -1740,7 +1754,6 @@ static struct cpufreq_driver amd_pstate_
|
|
.set_boost = amd_pstate_set_boost,
|
|
.name = "amd-pstate-epp",
|
|
.attr = amd_pstate_epp_attr,
|
|
- .get_init_min_freq = amd_pstate_get_init_min_freq,
|
|
};
|
|
|
|
static int __init amd_pstate_set_driver(int mode_idx)
|
|
--- a/drivers/cpufreq/amd-pstate.h
|
|
+++ b/drivers/cpufreq/amd-pstate.h
|
|
@@ -28,7 +28,7 @@ struct amd_aperf_mperf {
|
|
/**
|
|
* struct amd_cpudata - private CPU data for AMD P-State
|
|
* @cpu: CPU number
|
|
- * @max_freq_req: maximum frequency constraint request to apply
|
|
+ * @req: constraint request to apply
|
|
* @cppc_req_cached: cached performance request hints
|
|
* @highest_perf: the maximum performance an individual processor may reach,
|
|
* assuming ideal conditions
|
|
@@ -68,7 +68,7 @@ struct amd_aperf_mperf {
|
|
struct amd_cpudata {
|
|
int cpu;
|
|
|
|
- struct freq_qos_request max_freq_req;
|
|
+ struct freq_qos_request req[2];
|
|
u64 cppc_req_cached;
|
|
|
|
u32 highest_perf;
|
|
--- a/drivers/cpufreq/cpufreq.c
|
|
+++ b/drivers/cpufreq/cpufreq.c
|
|
@@ -1380,7 +1380,6 @@ static int cpufreq_online(unsigned int c
|
|
bool new_policy;
|
|
unsigned long flags;
|
|
unsigned int j;
|
|
- u32 init_min_freq = FREQ_QOS_MIN_DEFAULT_VALUE;
|
|
int ret;
|
|
|
|
pr_debug("%s: bringing CPU%u online\n", __func__, cpu);
|
|
@@ -1465,12 +1464,9 @@ static int cpufreq_online(unsigned int c
|
|
goto out_destroy_policy;
|
|
}
|
|
|
|
- if (cpufreq_driver->get_init_min_freq)
|
|
- init_min_freq = cpufreq_driver->get_init_min_freq(policy);
|
|
-
|
|
ret = freq_qos_add_request(&policy->constraints,
|
|
policy->min_freq_req, FREQ_QOS_MIN,
|
|
- init_min_freq);
|
|
+ FREQ_QOS_MIN_DEFAULT_VALUE);
|
|
if (ret < 0) {
|
|
/*
|
|
* So we don't call freq_qos_remove_request() for an
|
|
--- a/include/linux/cpufreq.h
|
|
+++ b/include/linux/cpufreq.h
|
|
@@ -414,12 +414,6 @@ struct cpufreq_driver {
|
|
* policy is properly initialized, but before the governor is started.
|
|
*/
|
|
void (*register_em)(struct cpufreq_policy *policy);
|
|
-
|
|
- /*
|
|
- * Set by drivers that want to initialize the policy->min_freq_req with
|
|
- * a value different from the default value (0) in cpufreq core.
|
|
- */
|
|
- int (*get_init_min_freq)(struct cpufreq_policy *policy);
|
|
};
|
|
|
|
/* flags */
|