Skip to content

Commit f61effa

Browse files
pierregondoissforshee
authored andcommitted
NVIDIA: VR: 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> Tested-by: Sumit Gupta <sumitg@nvidia.com> Reviewed-by: Sumit Gupta <sumitg@nvidia.com> (backported from https://lore.kernel.org/lkml/20260423084731.1090384-2-pierre.gondois@arm.com/) [sforshee: adjust context] Signed-off-by: Seth Forshee <sforshee@nvidia.com>
1 parent dc82c18 commit f61effa

11 files changed

Lines changed: 55 additions & 43 deletions

drivers/cpufreq/amd-pstate.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,12 +1001,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
10011001

10021002
perf = READ_ONCE(cpudata->perf);
10031003

1004-
policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
1005-
cpudata->nominal_freq,
1006-
perf.lowest_perf);
1007-
policy->cpuinfo.max_freq = policy->max = perf_to_freq(perf,
1008-
cpudata->nominal_freq,
1009-
perf.highest_perf);
1004+
policy->cpuinfo.min_freq = perf_to_freq(perf,
1005+
cpudata->nominal_freq,
1006+
perf.lowest_perf);
1007+
policy->cpuinfo.max_freq = perf_to_freq(perf,
1008+
cpudata->nominal_freq,
1009+
perf.highest_perf);
10101010

10111011
ret = amd_pstate_cppc_enable(policy);
10121012
if (ret)
@@ -1490,12 +1490,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14901490

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

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

15011501
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
@@ -611,6 +611,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
611611
unsigned int cpu = policy->cpu;
612612
struct cppc_cpudata *cpu_data;
613613
struct cppc_perf_caps *caps;
614+
unsigned int min, max;
614615
int ret;
615616

616617
cpu_data = cppc_cpufreq_get_cpu_data(cpu);
@@ -621,21 +622,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
621622
caps = &cpu_data->perf_caps;
622623
policy->driver_data = cpu_data;
623624

625+
min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
626+
max = cppc_perf_to_khz(caps, policy->boost_enabled ?
627+
caps->highest_perf : caps->nominal_perf);
628+
624629
/*
625630
* Set min to lowest nonlinear perf to avoid any efficiency penalty (see
626631
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
627632
*/
628-
policy->min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
629-
policy->max = cppc_perf_to_khz(caps, policy->boost_enabled ?
630-
caps->highest_perf : caps->nominal_perf);
633+
policy->min = min;
631634

632635
/*
633636
* Set cpuinfo.min_freq to Lowest to make the full range of performance
634637
* available if userspace wants to use any perf between lowest & lowest
635638
* nonlinear perf
636639
*/
637640
policy->cpuinfo.min_freq = cppc_perf_to_khz(caps, caps->lowest_perf);
638-
policy->cpuinfo.max_freq = policy->max;
641+
policy->cpuinfo.max_freq = max;
639642

640643
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
641644
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
@@ -1447,6 +1447,14 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14471447
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
14481448

14491449
if (new_policy) {
1450+
unsigned int min, max;
1451+
1452+
/* Use policy->min/max set by the driver as QoS requests. */
1453+
min = max(FREQ_QOS_MIN_DEFAULT_VALUE, policy->min);
1454+
if (policy->max)
1455+
max = min(FREQ_QOS_MAX_DEFAULT_VALUE, policy->max);
1456+
else
1457+
max = FREQ_QOS_MAX_DEFAULT_VALUE;
14501458
for_each_cpu(j, policy->related_cpus) {
14511459
per_cpu(cpufreq_cpu_data, j) = policy;
14521460
add_cpu_dev_symlink(policy, j, get_cpu_device(j));
@@ -1463,18 +1471,25 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14631471

14641472
ret = freq_qos_add_request(&policy->constraints,
14651473
&policy->min_freq_req, FREQ_QOS_MIN,
1466-
FREQ_QOS_MIN_DEFAULT_VALUE);
1474+
min);
14671475
if (ret < 0)
14681476
goto out_destroy_policy;
14691477

14701478
ret = freq_qos_add_request(&policy->constraints,
14711479
&policy->max_freq_req, FREQ_QOS_MAX,
1472-
FREQ_QOS_MAX_DEFAULT_VALUE);
1480+
max);
14731481
if (ret < 0)
14741482
goto out_destroy_policy;
14751483

14761484
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
14771485
CPUFREQ_CREATE_POLICY, policy);
1486+
1487+
/*
1488+
* If the driver didn't set QoS constraints, policy->min/max still
1489+
* need to be set as they are used to clamp frequency requests.
1490+
*/
1491+
policy->min = policy->min ? policy->min : policy->cpuinfo.min_freq;
1492+
policy->max = policy->max ? policy->max : policy->cpuinfo.max_freq;
14781493
}
14791494

14801495
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
@@ -3080,9 +3080,6 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
30803080
policy->cpuinfo.max_freq = READ_ONCE(global.no_turbo) ?
30813081
cpu->pstate.max_freq : cpu->pstate.turbo_freq;
30823082

3083-
policy->min = policy->cpuinfo.min_freq;
3084-
policy->max = policy->cpuinfo.max_freq;
3085-
30863083
intel_pstate_init_acpi_perf_limits(policy);
30873084

30883085
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)