From 649d296be0c7f0df6e71b4fca25fdbe75cb3994e Mon Sep 17 00:00:00 2001 From: Oleksandr Natalenko 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 --- 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 */