Skip to content

Commit 6e39ba4

Browse files
pierregondoisrafaeljw
authored andcommitted
cpufreq: Add boost_freq_req QoS request
The Power Management Quality of Service (PM QoS) allows to aggregate constraints from multiple entities. It is currently used to manage the min/max frequency of a given policy. Frequency constraints can come for instance from: - Thermal framework: acpi_thermal_cpufreq_init() - Firmware: _PPC objects: acpi_processor_ppc_init() - User: by setting policyX/scaling_[min|max]_freq The minimum of the max frequency constraints is used to compute the resulting maximum allowed frequency. When enabling boost frequencies, the same frequency request object (policy->max_freq_req) as to handle requests from users is used. As a result, when setting: - scaling_max_freq - boost The last sysfs file used overwrites the request from the other sysfs file. To avoid this, create a per-policy boost_freq_req to save the boost constraints instead of overwriting the last scaling_max_freq constraint. policy_set_boost() calls the cpufreq set_boost callback. Update the newly added boost_freq_req request from there: - whenever boost is toggled - to cover all possible paths In the existing .set_boost() callbacks: - Don't update policy->max as this is done through the qos notifier cpufreq_notifier_max() which calls cpufreq_set_policy(). - Remove freq_qos_update_request() calls as the qos request is now done in policy_set_boost() and updates the new boost_freq_req $ ## Init state scaling_max_freq:1000000 cpuinfo_max_freq:1000000 $ echo 700000 > scaling_max_freq scaling_max_freq:700000 cpuinfo_max_freq:1000000 $ echo 1 > ../boost scaling_max_freq:1200000 cpuinfo_max_freq:1200000 $ echo 800000 > scaling_max_freq scaling_max_freq:800000 cpuinfo_max_freq:1200000 $ ## Final step: $ ## Without the patches: $ echo 0 > ../boost scaling_max_freq:1000000 cpuinfo_max_freq:1000000 $ ## With the patches: $ echo 0 > ../boost scaling_max_freq:800000 cpuinfo_max_freq:1000000 Note: cpufreq_frequency_table_cpuinfo() updates policy->min and max from: A. cpufreq_boost_set_sw() \-cpufreq_frequency_table_cpuinfo() B. cpufreq_policy_online() \-cpufreq_table_validate_and_sort() \-cpufreq_frequency_table_cpuinfo() Keep these updates as some drivers expect policy->min and max to be set through B. Reviewed-by: Lifeng Zheng <zhenglifeng1@huawei.com> Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Link: https://patch.msgid.link/20260326204404.1401849-3-pierre.gondois@arm.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 04aa9d0 commit 6e39ba4

4 files changed

Lines changed: 34 additions & 25 deletions

File tree

drivers/cpufreq/amd-pstate.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,6 @@ static int amd_pstate_cpu_boost_update(struct cpufreq_policy *policy, bool on)
769769
else if (policy->cpuinfo.max_freq > nominal_freq)
770770
policy->cpuinfo.max_freq = nominal_freq;
771771

772-
policy->max = policy->cpuinfo.max_freq;
773-
774772
if (cppc_state == AMD_PSTATE_PASSIVE) {
775773
ret = freq_qos_update_request(&cpudata->req[1], policy->cpuinfo.max_freq);
776774
if (ret < 0)

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -807,17 +807,11 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
807807
{
808808
struct cppc_cpudata *cpu_data = policy->driver_data;
809809
struct cppc_perf_caps *caps = &cpu_data->perf_caps;
810-
int ret;
811810

812811
if (state)
813-
policy->max = cppc_perf_to_khz(caps, caps->highest_perf);
812+
policy->cpuinfo.max_freq = cppc_perf_to_khz(caps, caps->highest_perf);
814813
else
815-
policy->max = cppc_perf_to_khz(caps, caps->nominal_perf);
816-
policy->cpuinfo.max_freq = policy->max;
817-
818-
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
819-
if (ret < 0)
820-
return ret;
814+
policy->cpuinfo.max_freq = cppc_perf_to_khz(caps, caps->nominal_perf);
821815

822816
return 0;
823817
}

drivers/cpufreq/cpufreq.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,19 @@ static int policy_set_boost(struct cpufreq_policy *policy, bool enable)
609609
policy->boost_enabled = enable;
610610

611611
ret = cpufreq_driver->set_boost(policy, enable);
612-
if (ret)
612+
if (ret) {
613613
policy->boost_enabled = !policy->boost_enabled;
614+
return ret;
615+
}
614616

615-
return ret;
617+
ret = freq_qos_update_request(policy->boost_freq_req, policy->cpuinfo.max_freq);
618+
if (ret < 0) {
619+
policy->boost_enabled = !policy->boost_enabled;
620+
cpufreq_driver->set_boost(policy, policy->boost_enabled);
621+
return ret;
622+
}
623+
624+
return 0;
616625
}
617626

618627
static ssize_t store_local_boost(struct cpufreq_policy *policy,
@@ -1377,6 +1386,7 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
13771386
}
13781387

13791388
freq_qos_remove_request(policy->min_freq_req);
1389+
freq_qos_remove_request(policy->boost_freq_req);
13801390
kfree(policy->min_freq_req);
13811391

13821392
cpufreq_policy_put_kobj(policy);
@@ -1442,26 +1452,38 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14421452
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
14431453

14441454
if (new_policy) {
1455+
unsigned int count;
1456+
14451457
for_each_cpu(j, policy->related_cpus) {
14461458
per_cpu(cpufreq_cpu_data, j) = policy;
14471459
add_cpu_dev_symlink(policy, j, get_cpu_device(j));
14481460
}
14491461

1450-
policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req),
1462+
count = policy->boost_supported ? 3 : 2;
1463+
policy->min_freq_req = kzalloc(count * sizeof(*policy->min_freq_req),
14511464
GFP_KERNEL);
14521465
if (!policy->min_freq_req) {
14531466
ret = -ENOMEM;
14541467
goto out_destroy_policy;
14551468
}
14561469

1470+
if (policy->boost_supported) {
1471+
policy->boost_freq_req = policy->min_freq_req + 2;
1472+
1473+
ret = freq_qos_add_request(&policy->constraints,
1474+
policy->boost_freq_req,
1475+
FREQ_QOS_MAX,
1476+
policy->cpuinfo.max_freq);
1477+
if (ret < 0) {
1478+
policy->boost_freq_req = NULL;
1479+
goto out_destroy_policy;
1480+
}
1481+
}
1482+
14571483
ret = freq_qos_add_request(&policy->constraints,
14581484
policy->min_freq_req, FREQ_QOS_MIN,
14591485
FREQ_QOS_MIN_DEFAULT_VALUE);
14601486
if (ret < 0) {
1461-
/*
1462-
* So we don't call freq_qos_remove_request() for an
1463-
* uninitialized request.
1464-
*/
14651487
kfree(policy->min_freq_req);
14661488
policy->min_freq_req = NULL;
14671489
goto out_destroy_policy;
@@ -2785,16 +2807,10 @@ int cpufreq_boost_set_sw(struct cpufreq_policy *policy, int state)
27852807
return -ENXIO;
27862808

27872809
ret = cpufreq_frequency_table_cpuinfo(policy);
2788-
if (ret) {
2810+
if (ret)
27892811
pr_err("%s: Policy frequency update failed\n", __func__);
2790-
return ret;
2791-
}
2792-
2793-
ret = freq_qos_update_request(policy->max_freq_req, policy->max);
2794-
if (ret < 0)
2795-
return ret;
27962812

2797-
return 0;
2813+
return ret;
27982814
}
27992815
EXPORT_SYMBOL_GPL(cpufreq_boost_set_sw);
28002816

include/linux/cpufreq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct cpufreq_policy {
8181
struct freq_constraints constraints;
8282
struct freq_qos_request *min_freq_req;
8383
struct freq_qos_request *max_freq_req;
84+
struct freq_qos_request *boost_freq_req;
8485

8586
struct cpufreq_frequency_table *freq_table;
8687
enum cpufreq_table_sorting freq_table_sorted;

0 commit comments

Comments
 (0)