Skip to content

Commit fff3957

Browse files
committed
cpufreq/amd-pstate: Always write EPP value when updating perf
For MSR systems the EPP value is in the same register as perf targets and so divding them into two separate MSR writes is wasteful. In msr_update_perf(), update both EPP and perf values in one write to MSR_AMD_CPPC_REQ, and cache them if successful. To accomplish this plumb the EPP value into the update_perf call and modify all its callers to check the return value. As this unifies calls, ensure that the MSR write is necessary before flushing a write out. Also drop the comparison from the passive flow tracing. Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com> Link: https://lore.kernel.org/r/20241209185248.16301-13-mario.limonciello@amd.com Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
1 parent b3781f3 commit fff3957

File tree

2 files changed

+56
-59
lines changed

2 files changed

+56
-59
lines changed

drivers/cpufreq/amd-pstate-trace.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ TRACE_EVENT(amd_pstate_perf,
3232
u64 aperf,
3333
u64 tsc,
3434
unsigned int cpu_id,
35-
bool changed,
3635
bool fast_switch
3736
),
3837

@@ -44,7 +43,6 @@ TRACE_EVENT(amd_pstate_perf,
4443
aperf,
4544
tsc,
4645
cpu_id,
47-
changed,
4846
fast_switch
4947
),
5048

@@ -57,7 +55,6 @@ TRACE_EVENT(amd_pstate_perf,
5755
__field(unsigned long long, aperf)
5856
__field(unsigned long long, tsc)
5957
__field(unsigned int, cpu_id)
60-
__field(bool, changed)
6158
__field(bool, fast_switch)
6259
),
6360

@@ -70,11 +67,10 @@ TRACE_EVENT(amd_pstate_perf,
7067
__entry->aperf = aperf;
7168
__entry->tsc = tsc;
7269
__entry->cpu_id = cpu_id;
73-
__entry->changed = changed;
7470
__entry->fast_switch = fast_switch;
7571
),
7672

77-
TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
73+
TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u fast_switch=%s",
7874
(unsigned long)__entry->min_perf,
7975
(unsigned long)__entry->target_perf,
8076
(unsigned long)__entry->capacity,
@@ -83,7 +79,6 @@ TRACE_EVENT(amd_pstate_perf,
8379
(unsigned long long)__entry->aperf,
8480
(unsigned long long)__entry->tsc,
8581
(unsigned int)__entry->cpu_id,
86-
(__entry->changed) ? "true" : "false",
8782
(__entry->fast_switch) ? "true" : "false"
8883
)
8984
);

drivers/cpufreq/amd-pstate.c

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -222,25 +222,47 @@ static s16 shmem_get_epp(struct amd_cpudata *cpudata)
222222
}
223223

224224
static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
225-
u32 des_perf, u32 max_perf, bool fast_switch)
225+
u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
226226
{
227+
u64 value, prev;
228+
229+
value = prev = READ_ONCE(cpudata->cppc_req_cached);
230+
231+
value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK |
232+
AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK);
233+
value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf);
234+
value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf);
235+
value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf);
236+
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, epp);
237+
238+
if (value == prev)
239+
return 0;
240+
227241
if (fast_switch) {
228-
wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
242+
wrmsrl(MSR_AMD_CPPC_REQ, value);
229243
return 0;
244+
} else {
245+
int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
246+
247+
if (ret)
248+
return ret;
230249
}
231250

232-
return wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
233-
READ_ONCE(cpudata->cppc_req_cached));
251+
WRITE_ONCE(cpudata->cppc_req_cached, value);
252+
WRITE_ONCE(cpudata->epp_cached, epp);
253+
254+
return 0;
234255
}
235256

236257
DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
237258

238259
static inline int amd_pstate_update_perf(struct amd_cpudata *cpudata,
239260
u32 min_perf, u32 des_perf,
240-
u32 max_perf, bool fast_switch)
261+
u32 max_perf, u32 epp,
262+
bool fast_switch)
241263
{
242264
return static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
243-
max_perf, fast_switch);
265+
max_perf, epp, fast_switch);
244266
}
245267

246268
static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
@@ -261,6 +283,7 @@ static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
261283
return ret;
262284
}
263285

286+
/* update both so that msr_update_perf() can effectively check */
264287
WRITE_ONCE(cpudata->epp_cached, epp);
265288
WRITE_ONCE(cpudata->cppc_req_cached, value);
266289

@@ -459,12 +482,18 @@ static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
459482
return static_call(amd_pstate_init_perf)(cpudata);
460483
}
461484

462-
static int shmem_update_perf(struct amd_cpudata *cpudata,
463-
u32 min_perf, u32 des_perf,
464-
u32 max_perf, bool fast_switch)
485+
static int shmem_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
486+
u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
465487
{
466488
struct cppc_perf_ctrls perf_ctrls;
467489

490+
if (cppc_state == AMD_PSTATE_ACTIVE) {
491+
int ret = shmem_set_epp(cpudata, epp);
492+
493+
if (ret)
494+
return ret;
495+
}
496+
468497
perf_ctrls.max_perf = max_perf;
469498
perf_ctrls.min_perf = min_perf;
470499
perf_ctrls.desired_perf = des_perf;
@@ -510,9 +539,7 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
510539
{
511540
unsigned long max_freq;
512541
struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
513-
u64 prev = READ_ONCE(cpudata->cppc_req_cached);
514542
u32 nominal_perf = READ_ONCE(cpudata->nominal_perf);
515-
u64 value = prev;
516543

517544
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
518545

@@ -528,27 +555,14 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf,
528555
if (!cpudata->boost_supported)
529556
max_perf = min_t(unsigned long, nominal_perf, max_perf);
530557

531-
value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK |
532-
AMD_CPPC_DES_PERF_MASK);
533-
value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, max_perf);
534-
value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, des_perf);
535-
value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, min_perf);
536-
537558
if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
538559
trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
539560
cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
540-
cpudata->cpu, (value != prev), fast_switch);
561+
cpudata->cpu, fast_switch);
541562
}
542563

543-
if (value == prev)
544-
goto cpufreq_policy_put;
564+
amd_pstate_update_perf(cpudata, min_perf, des_perf, max_perf, 0, fast_switch);
545565

546-
WRITE_ONCE(cpudata->cppc_req_cached, value);
547-
548-
amd_pstate_update_perf(cpudata, min_perf, des_perf,
549-
max_perf, fast_switch);
550-
551-
cpufreq_policy_put:
552566
cpufreq_cpu_put(policy);
553567
}
554568

@@ -1544,36 +1558,24 @@ static void amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
15441558
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
15451559
{
15461560
struct amd_cpudata *cpudata = policy->driver_data;
1547-
u64 value;
1561+
u32 epp;
15481562

15491563
amd_pstate_update_min_max_limit(policy);
15501564

1551-
value = READ_ONCE(cpudata->cppc_req_cached);
1552-
1553-
value &= ~(AMD_CPPC_MAX_PERF_MASK | AMD_CPPC_MIN_PERF_MASK |
1554-
AMD_CPPC_DES_PERF_MASK | AMD_CPPC_EPP_PERF_MASK);
1555-
value |= FIELD_PREP(AMD_CPPC_MAX_PERF_MASK, cpudata->max_limit_perf);
1556-
value |= FIELD_PREP(AMD_CPPC_DES_PERF_MASK, 0);
1557-
value |= FIELD_PREP(AMD_CPPC_MIN_PERF_MASK, cpudata->min_limit_perf);
1558-
15591565
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
1560-
WRITE_ONCE(cpudata->epp_cached, 0);
1561-
value |= FIELD_PREP(AMD_CPPC_EPP_PERF_MASK, cpudata->epp_cached);
1562-
1563-
WRITE_ONCE(cpudata->cppc_req_cached, value);
1566+
epp = 0;
1567+
else
1568+
epp = READ_ONCE(cpudata->epp_cached);
15641569

15651570
if (trace_amd_pstate_epp_perf_enabled()) {
1566-
trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
1567-
cpudata->epp_cached,
1571+
trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf, epp,
15681572
cpudata->min_limit_perf,
15691573
cpudata->max_limit_perf,
15701574
policy->boost_enabled);
15711575
}
15721576

1573-
amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
1574-
cpudata->max_limit_perf, false);
1575-
1576-
return amd_pstate_set_epp(cpudata, READ_ONCE(cpudata->epp_cached));
1577+
return amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
1578+
cpudata->max_limit_perf, epp, false);
15771579
}
15781580

15791581
static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
@@ -1602,7 +1604,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
16021604
return 0;
16031605
}
16041606

1605-
static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
1607+
static int amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
16061608
{
16071609
u64 max_perf;
16081610
int ret;
@@ -1620,17 +1622,19 @@ static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
16201622
max_perf, cpudata->boost_state);
16211623
}
16221624

1623-
amd_pstate_update_perf(cpudata, 0, 0, max_perf, false);
1624-
amd_pstate_set_epp(cpudata, cpudata->epp_cached);
1625+
return amd_pstate_update_perf(cpudata, 0, 0, max_perf, cpudata->epp_cached, false);
16251626
}
16261627

16271628
static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy)
16281629
{
16291630
struct amd_cpudata *cpudata = policy->driver_data;
1631+
int ret;
16301632

16311633
pr_debug("AMD CPU Core %d going online\n", cpudata->cpu);
16321634

1633-
amd_pstate_epp_reenable(cpudata);
1635+
ret = amd_pstate_epp_reenable(cpudata);
1636+
if (ret)
1637+
return ret;
16341638
cpudata->suspended = false;
16351639

16361640
return 0;
@@ -1654,10 +1658,8 @@ static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy)
16541658
min_perf, min_perf, policy->boost_enabled);
16551659
}
16561660

1657-
amd_pstate_update_perf(cpudata, min_perf, 0, min_perf, false);
1658-
amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
1659-
1660-
return 0;
1661+
return amd_pstate_update_perf(cpudata, min_perf, 0, min_perf,
1662+
AMD_CPPC_EPP_BALANCE_POWERSAVE, false);
16611663
}
16621664

16631665
static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)

0 commit comments

Comments
 (0)