Skip to content

Commit 192cdb1

Browse files
committed
cpufreq: intel_pstate: Refine computation of P-state for given frequency
On systems using HWP, if a given frequency is equal to the maximum turbo frequency or the maximum non-turbo frequency, the HWP performance level corresponding to it is already known and can be used directly without any computation. Accordingly, adjust the code to use the known HWP performance levels in the cases mentioned above. This also helps to avoid limiting CPU capacity artificially in some cases when the BIOS produces the HWP_CAP numbers using a different E-core-to-P-core performance scaling factor than expected by the kernel. Fixes: f5c8cf2 ("cpufreq: intel_pstate: hybrid: Use known scaling factor for P-cores") Cc: 6.1+ <stable@vger.kernel.org> # 6.1+ Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 6613476 commit 192cdb1

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

drivers/cpufreq/intel_pstate.c

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,30 @@ static int intel_pstate_cppc_get_scaling(int cpu)
529529
}
530530
#endif /* CONFIG_ACPI_CPPC_LIB */
531531

532+
static int intel_pstate_freq_to_hwp_rel(struct cpudata *cpu, int freq,
533+
unsigned int relation)
534+
{
535+
if (freq == cpu->pstate.turbo_freq)
536+
return cpu->pstate.turbo_pstate;
537+
538+
if (freq == cpu->pstate.max_freq)
539+
return cpu->pstate.max_pstate;
540+
541+
switch (relation) {
542+
case CPUFREQ_RELATION_H:
543+
return freq / cpu->pstate.scaling;
544+
case CPUFREQ_RELATION_C:
545+
return DIV_ROUND_CLOSEST(freq, cpu->pstate.scaling);
546+
}
547+
548+
return DIV_ROUND_UP(freq, cpu->pstate.scaling);
549+
}
550+
551+
static int intel_pstate_freq_to_hwp(struct cpudata *cpu, int freq)
552+
{
553+
return intel_pstate_freq_to_hwp_rel(cpu, freq, CPUFREQ_RELATION_L);
554+
}
555+
532556
/**
533557
* intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels.
534558
* @cpu: Target CPU.
@@ -546,6 +570,7 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
546570
int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
547571
int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
548572
int scaling = cpu->pstate.scaling;
573+
int freq;
549574

550575
pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
551576
pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
@@ -559,16 +584,16 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
559584
cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
560585
perf_ctl_scaling);
561586

562-
cpu->pstate.max_pstate_physical =
563-
DIV_ROUND_UP(perf_ctl_max_phys * perf_ctl_scaling,
564-
scaling);
587+
freq = perf_ctl_max_phys * perf_ctl_scaling;
588+
cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq);
565589

566-
cpu->pstate.min_freq = cpu->pstate.min_pstate * perf_ctl_scaling;
590+
freq = cpu->pstate.min_pstate * perf_ctl_scaling;
591+
cpu->pstate.min_freq = freq;
567592
/*
568593
* Cast the min P-state value retrieved via pstate_funcs.get_min() to
569594
* the effective range of HWP performance levels.
570595
*/
571-
cpu->pstate.min_pstate = DIV_ROUND_UP(cpu->pstate.min_freq, scaling);
596+
cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, freq);
572597
}
573598

574599
static inline void update_turbo_state(void)
@@ -2528,13 +2553,12 @@ static void intel_pstate_update_perf_limits(struct cpudata *cpu,
25282553
* abstract values to represent performance rather than pure ratios.
25292554
*/
25302555
if (hwp_active && cpu->pstate.scaling != perf_ctl_scaling) {
2531-
int scaling = cpu->pstate.scaling;
25322556
int freq;
25332557

25342558
freq = max_policy_perf * perf_ctl_scaling;
2535-
max_policy_perf = DIV_ROUND_UP(freq, scaling);
2559+
max_policy_perf = intel_pstate_freq_to_hwp(cpu, freq);
25362560
freq = min_policy_perf * perf_ctl_scaling;
2537-
min_policy_perf = DIV_ROUND_UP(freq, scaling);
2561+
min_policy_perf = intel_pstate_freq_to_hwp(cpu, freq);
25382562
}
25392563

25402564
pr_debug("cpu:%d min_policy_perf:%d max_policy_perf:%d\n",
@@ -2908,18 +2932,7 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
29082932

29092933
cpufreq_freq_transition_begin(policy, &freqs);
29102934

2911-
switch (relation) {
2912-
case CPUFREQ_RELATION_L:
2913-
target_pstate = DIV_ROUND_UP(freqs.new, cpu->pstate.scaling);
2914-
break;
2915-
case CPUFREQ_RELATION_H:
2916-
target_pstate = freqs.new / cpu->pstate.scaling;
2917-
break;
2918-
default:
2919-
target_pstate = DIV_ROUND_CLOSEST(freqs.new, cpu->pstate.scaling);
2920-
break;
2921-
}
2922-
2935+
target_pstate = intel_pstate_freq_to_hwp_rel(cpu, freqs.new, relation);
29232936
target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, false);
29242937

29252938
freqs.new = target_pstate * cpu->pstate.scaling;
@@ -2937,7 +2950,7 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
29372950

29382951
update_turbo_state();
29392952

2940-
target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling);
2953+
target_pstate = intel_pstate_freq_to_hwp(cpu, target_freq);
29412954

29422955
target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, true);
29432956

0 commit comments

Comments
 (0)