Skip to content

Commit c0eebd8

Browse files
pierregondoisjamieNguyenNVIDIA
authored andcommitted
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>
1 parent 1ef6d20 commit c0eebd8

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
@@ -1003,12 +1003,12 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
10031003

10041004
perf = READ_ONCE(cpudata->perf);
10051005

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

10131013
ret = amd_pstate_cppc_enable(policy);
10141014
if (ret)
@@ -1492,12 +1492,12 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy)
14921492

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

1495-
policy->cpuinfo.min_freq = policy->min = perf_to_freq(perf,
1496-
cpudata->nominal_freq,
1497-
perf.lowest_perf);
1498-
policy->cpuinfo.max_freq = policy->max = perf_to_freq(perf,
1499-
cpudata->nominal_freq,
1500-
perf.highest_perf);
1495+
policy->cpuinfo.min_freq = perf_to_freq(perf,
1496+
cpudata->nominal_freq,
1497+
perf.lowest_perf);
1498+
policy->cpuinfo.max_freq = perf_to_freq(perf,
1499+
cpudata->nominal_freq,
1500+
perf.highest_perf);
15011501
policy->driver_data = cpudata;
15021502

15031503
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
@@ -613,6 +613,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
613613
unsigned int cpu = policy->cpu;
614614
struct cppc_cpudata *cpu_data;
615615
struct cppc_perf_caps *caps;
616+
unsigned int min, max;
616617
int ret;
617618

618619
cpu_data = cppc_cpufreq_get_cpu_data(cpu);
@@ -623,21 +624,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
623624
caps = &cpu_data->perf_caps;
624625
policy->driver_data = cpu_data;
625626

627+
min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
628+
max = cppc_perf_to_khz(caps, policy->boost_enabled ?
629+
caps->highest_perf : caps->nominal_perf);
630+
626631
/*
627632
* Set min to lowest nonlinear perf to avoid any efficiency penalty (see
628633
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
629634
*/
630-
policy->min = cppc_perf_to_khz(caps, caps->lowest_nonlinear_perf);
631-
policy->max = cppc_perf_to_khz(caps, policy->boost_enabled ?
632-
caps->highest_perf : caps->nominal_perf);
635+
policy->min = min;
633636

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

642645
policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu);
643646
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
@@ -1435,6 +1435,14 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14351435
cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
14361436

14371437
if (new_policy) {
1438+
unsigned int min, max;
1439+
1440+
/* Use policy->min/max set by the driver as QoS requests. */
1441+
min = max(FREQ_QOS_MIN_DEFAULT_VALUE, policy->min);
1442+
if (policy->max)
1443+
max = min(FREQ_QOS_MAX_DEFAULT_VALUE, policy->max);
1444+
else
1445+
max = FREQ_QOS_MAX_DEFAULT_VALUE;
14381446
for_each_cpu(j, policy->related_cpus) {
14391447
per_cpu(cpufreq_cpu_data, j) = policy;
14401448
add_cpu_dev_symlink(policy, j, get_cpu_device(j));
@@ -1449,7 +1457,7 @@ static int cpufreq_policy_online(struct cpufreq_policy *policy,
14491457

14501458
ret = freq_qos_add_request(&policy->constraints,
14511459
policy->min_freq_req, FREQ_QOS_MIN,
1452-
FREQ_QOS_MIN_DEFAULT_VALUE);
1460+
min);
14531461
if (ret < 0) {
14541462
/*
14551463
* So we don't call freq_qos_remove_request() for an
@@ -1469,14 +1477,21 @@ static int cpufreq_policy_online(struct cpufreq_policy *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
policy->max_freq_req = NULL;
14751483
goto out_destroy_policy;
14761484
}
14771485

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

14821497
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
@@ -50,16 +50,15 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
5050
max_freq = freq;
5151
}
5252

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

62-
if (policy->min == ~0)
61+
if (min_freq == ~0)
6362
return -EINVAL;
6463
else
6564
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
@@ -3113,9 +3113,6 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy)
31133113
policy->cpuinfo.max_freq = READ_ONCE(global.no_turbo) ?
31143114
cpu->pstate.max_freq : cpu->pstate.turbo_freq;
31153115

3116-
policy->min = policy->cpuinfo.min_freq;
3117-
policy->max = policy->cpuinfo.max_freq;
3118-
31193116
intel_pstate_init_acpi_perf_limits(policy);
31203117

31213118
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
@@ -126,9 +126,9 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
126126
dev_notice(dev, "no frequency table found, falling back "
127127
"to rate rounding.\n");
128128

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

0 commit comments

Comments
 (0)