[AMD Official Use Only - General] > -----Original Message----- > From: Meng, Li (Jassmine) <[email protected]> > Sent: Wednesday, November 29, 2023 2:55 PM > To: Rafael J . Wysocki <[email protected]>; Huang, Ray > <[email protected]> > Cc: [email protected]; [email protected]; [email protected]; > [email protected]; Shuah Khan <[email protected]>; linux- > [email protected]; Fontenot, Nathan <[email protected]>; > Sharma, Deepak <[email protected]>; Deucher, Alexander > <[email protected]>; Limonciello, Mario > <[email protected]>; Huang, Shimmer > <[email protected]>; Yuan, Perry <[email protected]>; Du, > Xiaojian <[email protected]>; Viresh Kumar <[email protected]>; > Borislav Petkov <[email protected]>; Oleksandr Natalenko > <[email protected]>; Meng, Li (Jassmine) <[email protected]>; > Karny, Wyes <[email protected]> > Subject: [PATCH V11 5/7] cpufreq: amd-pstate: Update amd-pstate preferred > core ranking dynamically > > Preferred core rankings can be changed dynamically by the platform based on > the workload and platform conditions and accounting for thermals and aging. > When this occurs, cpu priority need to be set. > > Tested-by: Oleksandr Natalenko <[email protected]> > Reviewed-by: Mario Limonciello <[email protected]> > Reviewed-by: Wyes Karny <[email protected]> > Reviewed-by: Huang Rui <[email protected]> > Signed-off-by: Meng Li <[email protected]> > --- > drivers/cpufreq/amd-pstate.c | 46 > ++++++++++++++++++++++++++++++++++++ > include/linux/amd-pstate.h | 6 +++++ > 2 files changed, 52 insertions(+) > > diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c > index 74dcf63d75f9..88df6510dcc0 100644 > --- a/drivers/cpufreq/amd-pstate.c > +++ b/drivers/cpufreq/amd-pstate.c > @@ -312,6 +312,7 @@ static int pstate_init_perf(struct amd_cpudata > *cpudata) > WRITE_ONCE(cpudata->nominal_perf, > AMD_CPPC_NOMINAL_PERF(cap1)); > WRITE_ONCE(cpudata->lowest_nonlinear_perf, > AMD_CPPC_LOWNONLIN_PERF(cap1)); > WRITE_ONCE(cpudata->lowest_perf, > AMD_CPPC_LOWEST_PERF(cap1)); > + WRITE_ONCE(cpudata->prefcore_ranking, > AMD_CPPC_HIGHEST_PERF(cap1)); > > return 0; > } > @@ -333,6 +334,7 @@ static int cppc_init_perf(struct amd_cpudata > *cpudata) > WRITE_ONCE(cpudata->lowest_nonlinear_perf, > cppc_perf.lowest_nonlinear_perf); > WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf); > + WRITE_ONCE(cpudata->prefcore_ranking, cppc_perf.highest_perf); > > if (cppc_state == AMD_PSTATE_ACTIVE) > return 0; > @@ -749,6 +751,34 @@ static void amd_pstate_init_prefcore(struct > amd_cpudata *cpudata) > schedule_work(&sched_prefcore_work); > } > > +static void amd_pstate_update_highest_perf(unsigned int cpu) { > + struct cpufreq_policy *policy; > + struct amd_cpudata *cpudata; > + u32 prev_high = 0, cur_high = 0; > + int ret; > + > + if ((!amd_pstate_prefcore) || (!cpudata->hw_prefcore)) > + return; > + > + ret = amd_pstate_get_highest_perf(cpu, &cur_high); > + if (ret) > + return; > + > + policy = cpufreq_cpu_get(cpu); > + cpudata = policy->driver_data; > + prev_high = READ_ONCE(cpudata->prefcore_ranking); > + > + if (prev_high != cur_high) { > + WRITE_ONCE(cpudata->prefcore_ranking, cur_high); > + > + if (cur_high < CPPC_MAX_PERF) > + sched_set_itmt_core_prio((int)cur_high, cpu); > + } > + > + cpufreq_cpu_put(policy); > +} > + > static int amd_pstate_cpu_init(struct cpufreq_policy *policy) { > int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; > @@ -920,6 +950,17 @@ static ssize_t show_amd_pstate_highest_perf(struct > cpufreq_policy *policy, > return sysfs_emit(buf, "%u\n", perf); > } > > +static ssize_t show_amd_pstate_prefcore_ranking(struct cpufreq_policy > *policy, > + char *buf) > +{ > + u32 perf; > + struct amd_cpudata *cpudata = policy->driver_data; > + > + perf = READ_ONCE(cpudata->prefcore_ranking); > + > + return sysfs_emit(buf, "%u\n", perf); > +} > + > static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy, > char *buf) > { > @@ -1133,6 +1174,7 @@ cpufreq_freq_attr_ro(amd_pstate_max_freq); > cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); > > cpufreq_freq_attr_ro(amd_pstate_highest_perf); > +cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking); > cpufreq_freq_attr_ro(amd_pstate_hw_prefcore); > cpufreq_freq_attr_rw(energy_performance_preference); > cpufreq_freq_attr_ro(energy_performance_available_preferences); > @@ -1143,6 +1185,7 @@ static struct freq_attr *amd_pstate_attr[] = { > &amd_pstate_max_freq, > &amd_pstate_lowest_nonlinear_freq, > &amd_pstate_highest_perf, > + &amd_pstate_prefcore_ranking, > &amd_pstate_hw_prefcore, > NULL, > }; > @@ -1151,6 +1194,7 @@ static struct freq_attr *amd_pstate_epp_attr[] = { > &amd_pstate_max_freq, > &amd_pstate_lowest_nonlinear_freq, > &amd_pstate_highest_perf, > + &amd_pstate_prefcore_ranking, > &amd_pstate_hw_prefcore, > &energy_performance_preference, > &energy_performance_available_preferences, > @@ -1491,6 +1535,7 @@ static struct cpufreq_driver amd_pstate_driver = { > .suspend = amd_pstate_cpu_suspend, > .resume = amd_pstate_cpu_resume, > .set_boost = amd_pstate_set_boost, > + .update_highest_perf = amd_pstate_update_highest_perf, > .name = "amd-pstate", > .attr = amd_pstate_attr, > }; > @@ -1505,6 +1550,7 @@ static struct cpufreq_driver > amd_pstate_epp_driver = { > .online = amd_pstate_epp_cpu_online, > .suspend = amd_pstate_epp_suspend, > .resume = amd_pstate_epp_resume, > + .update_highest_perf = amd_pstate_update_highest_perf, > .name = "amd-pstate-epp", > .attr = amd_pstate_epp_attr, > }; > diff --git a/include/linux/amd-pstate.h b/include/linux/amd-pstate.h index > 87e140e9e6db..426822612373 100644 > --- a/include/linux/amd-pstate.h > +++ b/include/linux/amd-pstate.h > @@ -39,11 +39,16 @@ struct amd_aperf_mperf { > * @cppc_req_cached: cached performance request hints > * @highest_perf: the maximum performance an individual processor may > reach, > * assuming ideal conditions > + * For platforms that do not support the preferred core feature, > the > + * highest_pef may be configured with 166 or 255, to avoid > max frequency > + * calculated wrongly. we take the fixed value as the > highest_perf. > * @nominal_perf: the maximum sustained performance level of the > processor, > * assuming ideal operating conditions > * @lowest_nonlinear_perf: the lowest performance level at which nonlinear > power > * savings are achieved > * @lowest_perf: the absolute lowest performance level of the processor > + * @prefcore_ranking: the preferred core ranking, the higher value indicates > a > higher > + * priority. > * @max_freq: the frequency that mapped to highest_perf > * @min_freq: the frequency that mapped to lowest_perf > * @nominal_freq: the frequency that mapped to nominal_perf @@ -73,6 > +78,7 @@ struct amd_cpudata { > u32 nominal_perf; > u32 lowest_nonlinear_perf; > u32 lowest_perf; > + u32 prefcore_ranking; > > u32 max_freq; > u32 min_freq; > -- > 2.34.1
Reviewed-by: Perry Yuan <[email protected]>
