Skip to content

Commit 9dd0cb0

Browse files
pierregondoisjamieNguyenNVIDIA
authored andcommitted
NVIDIA: SAUCE: cpufreq: Set policy->min and max as real QoS constraints
cpufreq_set_policy() will ultimately override the policy min/max values written in the .init() callback through: cpufreq_policy_online() \-cpufreq_init_policy() \-cpufreq_set_policy() \-/* Set policy->min/max */ Thus the policy min/max values provided are only temporary. There is an exception if CPUFREQ_NEED_INITIAL_FREQ_CHECK is set and: cpufreq_policy_online() \-cpufreq_init_policy() \-__cpufreq_driver_target() \-cpufreq_driver->target() is called. To avoid any regression, set policy->min/max in cpufreq.c if the values were not initialized. In this patch: - Setting policy->min or max value in driver .init() cb is interpreted as setting a QoS constraint. - Remove policy->min/max initialization in drivers if the values are similar to policy->cpuinfo.min_freq/max_freq. The only drivers where these values are different are: - gx-suspmod.c - cppc-cpufreq.c - longrun.c - For the cppc-cpufreq driver, the lowest non-linear freq. is used as a min QoS constraint as suggested at: https://lore.kernel.org/lkml/20260213100633.15413-1-zhangpengjie2@huawei.com/ Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> (backported from https://lore.kernel.org/lkml/20260423084731.1090384-2-pierre.gondois@arm.com/) Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
1 parent 6c6e63d commit 9dd0cb0

11 files changed

Lines changed: 51 additions & 39 deletions

drivers/cpufreq/amd-pstate.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,10 +1016,10 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
10161016

10171017
perf = READ_ONCE(cpudata->perf);
10181018

1019-
policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
1020-
cpudata->nominal_freq,
1021-
perf.lowest_perf);
1022-
policy->cpuinfo.max_freq = policy->max = cpudata->max_freq;
1019+
policy->cpuinfo.min_freq = perf_to_freq(perf,
1020+
cpudata->nominal_freq,
1021+
perf.lowest_perf);
1022+
policy->cpuinfo.max_freq = cpudata->max_freq;
10231023

10241024
ret = amd_pstate_cppc_enable(policy);
10251025
if (ret)
@@ -1491,10 +1491,10 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14911491

14921492
perf = READ_ONCE(cpudata->perf);
14931493

1494-
policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
1495-
cpudata->nominal_freq,
1496-
perf.lowest_perf);
1497-
policy->cpuinfo.max_freq = policy->max = cpudata->max_freq;
1494+
policy->cpuinfo.min_freq = perf_to_freq(perf,
1495+
cpudata->nominal_freq,
1496+
perf.lowest_perf);
1497+
policy->cpuinfo.max_freq = cpudata->max_freq;
14981498
policy->driver_data = cpudata;
14991499

15001500
ret = amd_pstate_cppc_enable(policy);

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
645645
unsigned int cpu = policy->cpu;
646646
struct cppc_cpudata *cpu_data;
647647
struct cppc_perf_caps *caps;
648+
unsigned int min, max;
648649
int ret;
649650

650651
cpu_data = cppc_cpufreq_get_cpu_data(cpu);
@@ -655,21 +656,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
655656
caps = &cpu_data->perf_caps;
656657
policy->driver_data = cpu_data;
657658

659+
min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
660+
max = cppc_perf_to_khz(caps, policy->boost_enabled ?
661+
caps->highest_perf : caps->nominal_perf);
662+
658663
/*
659664
* Set min to lowest nonlinear perf to avoid any efficiency penalty (see
660665
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
661666
*/
662-
policy->min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
663-
policy->max = cppc_perf_to_khz(caps, policy->boost_enabled ?
664-
caps->highest_perf : caps->nominal_perf);
667+
policy->min = min;
665668

666669
/*
667670
* Set cpuinfo.min_freq to Lowest to make the full range of performance
668671
* available if userspace wants to use any perf between lowest & lowest
669672
* nonlinear perf
670673
*/
671674
policy->cpuinfo.min_freq = cppc_perf_to_khz(caps, caps->lowest_perf);
672-
policy->cpuinfo.max_freq = policy->max;
675+
policy->cpuinfo.max_freq = max;
673676

674677
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
675678
policy->shared_type = cpu_data->shared_type;

drivers/cpufreq/cpufreq-nforce2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
355355
min_fsb = NFORCE2_MIN_FSB;
356356

357357
/* cpuinfo and default policy values */
358-
policy->min = policy->cpuinfo.min_freq = min_fsb * fid * 100;
359-
policy->max = policy->cpuinfo.max_freq = max_fsb * fid * 100;
358+
policy->cpuinfo.min_freq = min_fsb * fid * 100;
359+
policy->cpuinfo.max_freq = max_fsb * fid * 100;
360360

361361
return 0;
362362
}

drivers/cpufreq/cpufreq.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,14 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14531453
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
14541454

14551455
if (new_policy) {
1456+
unsigned int min, max;
1457+
1458+
/* Use policy->min/max set by the driver as QoS requests. */
1459+
min = max(FREQ_QOS_MIN_DEFAULT_VALUE, policy->min);
1460+
if (policy->max)
1461+
max = min(FREQ_QOS_MAX_DEFAULT_VALUE, policy->max);
1462+
else
1463+
max = FREQ_QOS_MAX_DEFAULT_VALUE;
14561464
for_each_cpu(j, policy->related_cpus) {
14571465
per_cpu(cpufreq_cpu_data, j) = policy;
14581466
add_cpu_dev_symlink(policy, j, get_cpu_device(j));
@@ -1469,18 +1477,25 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14691477

14701478
ret = freq_qos_add_request(&policy->constraints,
14711479
&policy->min_freq_req, FREQ_QOS_MIN,
1472-
FREQ_QOS_MIN_DEFAULT_VALUE);
1480+
min);
14731481
if (ret < 0)
14741482
goto out_destroy_policy;
14751483

14761484
ret = freq_qos_add_request(&policy->constraints,
14771485
&policy->max_freq_req, FREQ_QOS_MAX,
1478-
FREQ_QOS_MAX_DEFAULT_VALUE);
1486+
max);
14791487
if (ret < 0)
14801488
goto out_destroy_policy;
14811489

14821490
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
14831491
CPUFREQ_CREATE_POLICY, policy);
1492+
1493+
/*
1494+
* If the driver didn't set QoS constraints, policy->min/max still
1495+
* need to be set as they are used to clamp frequency requests.
1496+
*/
1497+
policy->min = policy->min ? policy->min : policy->cpuinfo.min_freq;
1498+
policy->max = policy->max ? policy->max : policy->cpuinfo.max_freq;
14841499
}
14851500

14861501
if (cpufreq_driver->get && has_target()) {

drivers/cpufreq/freq_table.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,15 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)
4949
max_freq = freq;
5050
}
5151

52-
policy->min = policy->cpuinfo.min_freq = min_freq;
53-
policy->max = max_freq;
52+
policy->cpuinfo.min_freq = min_freq;
5453
/*
5554
* If the driver has set its own cpuinfo.max_freq above max_freq, leave
5655
* it as is.
5756
*/
5857
if (policy->cpuinfo.max_freq < max_freq)
59-
policy->max = policy->cpuinfo.max_freq = max_freq;
58+
policy->cpuinfo.max_freq = max_freq;
6059

61-
if (policy->min == ~0)
60+
if (min_freq == ~0)
6261
return -EINVAL;
6362
else
6463
return 0;

drivers/cpufreq/gx-suspmod.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ static int cpufreq_gx_target(struct cpufreq_policy *policy,
397397

398398
static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
399399
{
400-
unsigned int maxfreq;
400+
unsigned int minfreq, maxfreq;
401401

402402
if (!policy || policy->cpu != 0)
403403
return -ENODEV;
@@ -418,10 +418,11 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
418418
policy->cpu = 0;
419419

420420
if (max_duration < POLICY_MIN_DIV)
421-
policy->min = maxfreq / max_duration;
421+
minfreq = maxfreq / max_duration;
422422
else
423-
policy->min = maxfreq / POLICY_MIN_DIV;
424-
policy->max = maxfreq;
423+
minfreq = maxfreq / POLICY_MIN_DIV;
424+
425+
policy->min = minfreq;
425426
policy->cpuinfo.min_freq = maxfreq / max_duration;
426427
policy->cpuinfo.max_freq = maxfreq;
427428

drivers/cpufreq/intel_pstate.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,9 +3049,6 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
30493049
policy->cpuinfo.max_freq = READ_ONCE(global.no_turbo) ?
30503050
cpu->pstate.max_freq : cpu->pstate.turbo_freq;
30513051

3052-
policy->min = policy->cpuinfo.min_freq;
3053-
policy->max = policy->cpuinfo.max_freq;
3054-
30553052
intel_pstate_init_acpi_perf_limits(policy);
30563053

30573054
policy->fast_switch_possible = true;

drivers/cpufreq/pcc-cpufreq.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,13 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
551551
goto out;
552552
}
553553

554-
policy->max = policy->cpuinfo.max_freq =
554+
policy->cpuinfo.max_freq =
555555
ioread32(&pcch_hdr->nominal) * 1000;
556-
policy->min = policy->cpuinfo.min_freq =
556+
policy->cpuinfo.min_freq =
557557
ioread32(&pcch_hdr->minimum_frequency) * 1000;
558558

559-
pr_debug("init: policy->max is %d, policy->min is %d\n",
560-
policy->max, policy->min);
559+
pr_debug("init: max_freq is %d, min_freq is %d\n",
560+
policy->cpuinfo.max_freq, policy->cpuinfo.min_freq);
561561
out:
562562
return result;
563563
}

drivers/cpufreq/pxa3xx-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
185185
int ret = -EINVAL;
186186

187187
/* set default policy and cpuinfo */
188-
policy->min = policy->cpuinfo.min_freq = 104000;
189-
policy->max = policy->cpuinfo.max_freq =
188+
policy->cpuinfo.min_freq = 104000;
189+
policy->cpuinfo.max_freq =
190190
(cpu_is_pxa320()) ? 806000 : 624000;
191191
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
192192

drivers/cpufreq/sh-cpufreq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
124124
dev_notice(dev, "no frequency table found, falling back "
125125
"to rate rounding.\n");
126126

127-
policy->min = policy->cpuinfo.min_freq =
127+
policy->cpuinfo.min_freq =
128128
(clk_round_rate(cpuclk, 1) + 500) / 1000;
129-
policy->max = policy->cpuinfo.max_freq =
129+
policy->cpuinfo.max_freq =
130130
(clk_round_rate(cpuclk, ~0UL) + 500) / 1000;
131131
}
132132

0 commit comments

Comments
 (0)