Skip to content

Commit 8dbab94

Browse files
committed
cpufreq: intel_pstate: Read all MSRs on the target CPU
Some of the MSR accesses in intel_pstate are carried out on the CPU that is running the code, but the values coming from them are used for the performance scaling of the other CPUs. This is problematic, for example, on hybrid platforms where MSR_TURBO_RATIO_LIMIT for P-cores and E-cores is different, so the values read from it on a P-core are generally not applicable to E-cores and the other way around. For this reason, make the driver access all MSRs on the target CPU on platforms using the "core" pstate_funcs callbacks which is the case for all of the hybrid platforms released to date. For this purpose, pass a CPU argument to the ->get_max(), ->get_max_physical(), ->get_min() and ->get_turbo() pstate_funcs callbacks and from there pass it to rdmsrl_on_cpu() or rdmsrl_safe_on_cpu() to access the MSR on the target CPU. Fixes: 46573fd ("cpufreq: intel_pstate: hybrid: Rework HWP calibration") Acked-by: Srinivas Pandruvada <[email protected]> Tested-by: Srinivas Pandruvada <[email protected]> Cc: 5.15+ <[email protected]> # 5.15+ Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 247f34f commit 8dbab94

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

drivers/cpufreq/intel_pstate.c

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,10 @@ static struct cpudata **all_cpu_data;
280280
* structure is used to store those callbacks.
281281
*/
282282
struct pstate_funcs {
283-
int (*get_max)(void);
284-
int (*get_max_physical)(void);
285-
int (*get_min)(void);
286-
int (*get_turbo)(void);
283+
int (*get_max)(int cpu);
284+
int (*get_max_physical)(int cpu);
285+
int (*get_min)(int cpu);
286+
int (*get_turbo)(int cpu);
287287
int (*get_scaling)(void);
288288
int (*get_cpu_scaling)(int cpu);
289289
int (*get_aperf_mperf_shift)(void);
@@ -531,12 +531,12 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
531531
{
532532
int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
533533
int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
534-
int perf_ctl_turbo = pstate_funcs.get_turbo();
534+
int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
535535
int turbo_freq = perf_ctl_turbo * perf_ctl_scaling;
536536
int scaling = cpu->pstate.scaling;
537537

538538
pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
539-
pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max());
539+
pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max(cpu->cpu));
540540
pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
541541
pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling);
542542
pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
@@ -1740,23 +1740,23 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
17401740
intel_pstate_update_epp_defaults(cpudata);
17411741
}
17421742

1743-
static int atom_get_min_pstate(void)
1743+
static int atom_get_min_pstate(int not_used)
17441744
{
17451745
u64 value;
17461746

17471747
rdmsrl(MSR_ATOM_CORE_RATIOS, value);
17481748
return (value >> 8) & 0x7F;
17491749
}
17501750

1751-
static int atom_get_max_pstate(void)
1751+
static int atom_get_max_pstate(int not_used)
17521752
{
17531753
u64 value;
17541754

17551755
rdmsrl(MSR_ATOM_CORE_RATIOS, value);
17561756
return (value >> 16) & 0x7F;
17571757
}
17581758

1759-
static int atom_get_turbo_pstate(void)
1759+
static int atom_get_turbo_pstate(int not_used)
17601760
{
17611761
u64 value;
17621762

@@ -1834,23 +1834,23 @@ static void atom_get_vid(struct cpudata *cpudata)
18341834
cpudata->vid.turbo = value & 0x7f;
18351835
}
18361836

1837-
static int core_get_min_pstate(void)
1837+
static int core_get_min_pstate(int cpu)
18381838
{
18391839
u64 value;
18401840

1841-
rdmsrl(MSR_PLATFORM_INFO, value);
1841+
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
18421842
return (value >> 40) & 0xFF;
18431843
}
18441844

1845-
static int core_get_max_pstate_physical(void)
1845+
static int core_get_max_pstate_physical(int cpu)
18461846
{
18471847
u64 value;
18481848

1849-
rdmsrl(MSR_PLATFORM_INFO, value);
1849+
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
18501850
return (value >> 8) & 0xFF;
18511851
}
18521852

1853-
static int core_get_tdp_ratio(u64 plat_info)
1853+
static int core_get_tdp_ratio(int cpu, u64 plat_info)
18541854
{
18551855
/* Check how many TDP levels present */
18561856
if (plat_info & 0x600000000) {
@@ -1860,13 +1860,13 @@ static int core_get_tdp_ratio(u64 plat_info)
18601860
int err;
18611861

18621862
/* Get the TDP level (0, 1, 2) to get ratios */
1863-
err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
1863+
err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
18641864
if (err)
18651865
return err;
18661866

18671867
/* TDP MSR are continuous starting at 0x648 */
18681868
tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03);
1869-
err = rdmsrl_safe(tdp_msr, &tdp_ratio);
1869+
err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio);
18701870
if (err)
18711871
return err;
18721872

@@ -1883,18 +1883,18 @@ static int core_get_tdp_ratio(u64 plat_info)
18831883
return -ENXIO;
18841884
}
18851885

1886-
static int core_get_max_pstate(void)
1886+
static int core_get_max_pstate(int cpu)
18871887
{
18881888
u64 tar;
18891889
u64 plat_info;
18901890
int max_pstate;
18911891
int tdp_ratio;
18921892
int err;
18931893

1894-
rdmsrl(MSR_PLATFORM_INFO, plat_info);
1894+
rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info);
18951895
max_pstate = (plat_info >> 8) & 0xFF;
18961896

1897-
tdp_ratio = core_get_tdp_ratio(plat_info);
1897+
tdp_ratio = core_get_tdp_ratio(cpu, plat_info);
18981898
if (tdp_ratio <= 0)
18991899
return max_pstate;
19001900

@@ -1903,7 +1903,7 @@ static int core_get_max_pstate(void)
19031903
return tdp_ratio;
19041904
}
19051905

1906-
err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar);
1906+
err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar);
19071907
if (!err) {
19081908
int tar_levels;
19091909

@@ -1918,13 +1918,13 @@ static int core_get_max_pstate(void)
19181918
return max_pstate;
19191919
}
19201920

1921-
static int core_get_turbo_pstate(void)
1921+
static int core_get_turbo_pstate(int cpu)
19221922
{
19231923
u64 value;
19241924
int nont, ret;
19251925

1926-
rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
1927-
nont = core_get_max_pstate();
1926+
rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
1927+
nont = core_get_max_pstate(cpu);
19281928
ret = (value) & 255;
19291929
if (ret <= nont)
19301930
ret = nont;
@@ -1952,13 +1952,13 @@ static int knl_get_aperf_mperf_shift(void)
19521952
return 10;
19531953
}
19541954

1955-
static int knl_get_turbo_pstate(void)
1955+
static int knl_get_turbo_pstate(int cpu)
19561956
{
19571957
u64 value;
19581958
int nont, ret;
19591959

1960-
rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
1961-
nont = core_get_max_pstate();
1960+
rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
1961+
nont = core_get_max_pstate(cpu);
19621962
ret = (((value) >> 8) & 0xFF);
19631963
if (ret <= nont)
19641964
ret = nont;
@@ -2025,10 +2025,10 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
20252025

20262026
static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
20272027
{
2028-
int perf_ctl_max_phys = pstate_funcs.get_max_physical();
2028+
int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
20292029
int perf_ctl_scaling = pstate_funcs.get_scaling();
20302030

2031-
cpu->pstate.min_pstate = pstate_funcs.get_min();
2031+
cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
20322032
cpu->pstate.max_pstate_physical = perf_ctl_max_phys;
20332033
cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
20342034

@@ -2044,8 +2044,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
20442044
}
20452045
} else {
20462046
cpu->pstate.scaling = perf_ctl_scaling;
2047-
cpu->pstate.max_pstate = pstate_funcs.get_max();
2048-
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
2047+
cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
2048+
cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
20492049
}
20502050

20512051
if (cpu->pstate.scaling == perf_ctl_scaling) {
@@ -3221,9 +3221,9 @@ static unsigned int force_load __initdata;
32213221

32223222
static int __init intel_pstate_msrs_not_valid(void)
32233223
{
3224-
if (!pstate_funcs.get_max() ||
3225-
!pstate_funcs.get_min() ||
3226-
!pstate_funcs.get_turbo())
3224+
if (!pstate_funcs.get_max(0) ||
3225+
!pstate_funcs.get_min(0) ||
3226+
!pstate_funcs.get_turbo(0))
32273227
return -ENODEV;
32283228

32293229
return 0;

0 commit comments

Comments
 (0)