diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-10-06 08:07:51 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-10-12 14:58:13 -0400 |
| commit | 0843e83c1a4aa67e08f424430526c948d591d5f1 (patch) | |
| tree | 3e86a9c1e9fe52ff303122874e4c3b2aff9551f3 /drivers/cpufreq | |
| parent | f00593a4bdd22e0885db89df8ee8afcc6867994f (diff) | |
cpufreq: intel_pstate: Proportional algorithm for Atom
The PID algorithm used by the intel_pstate driver tends to drive
performance to the minimum for workloads with utilization below the
setpoint, which is undesirable, so replace it with a modified
"proportional" algorithm on Atom.
The new algorithm will set the new P-state to be 1.25 times the
available maximum times the (frequency-invariant) utilization during
the previous sampling period except when the target P-state computed
this way is lower than the average P-state during the previous
sampling period. In the latter case, it will increase the target by
50% of the difference between it and the average P-state to prevent
performance from dropping down too fast in some cases.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Diffstat (limited to 'drivers/cpufreq')
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 1c7b91c5805b..6c8c897d0a2d 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -1232,6 +1232,7 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu) | |||
| 1232 | { | 1232 | { |
| 1233 | struct sample *sample = &cpu->sample; | 1233 | struct sample *sample = &cpu->sample; |
| 1234 | int32_t busy_frac, boost; | 1234 | int32_t busy_frac, boost; |
| 1235 | int target, avg_pstate; | ||
| 1235 | 1236 | ||
| 1236 | busy_frac = div_fp(sample->mperf, sample->tsc); | 1237 | busy_frac = div_fp(sample->mperf, sample->tsc); |
| 1237 | 1238 | ||
| @@ -1242,7 +1243,26 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu) | |||
| 1242 | busy_frac = boost; | 1243 | busy_frac = boost; |
| 1243 | 1244 | ||
| 1244 | sample->busy_scaled = busy_frac * 100; | 1245 | sample->busy_scaled = busy_frac * 100; |
| 1245 | return get_avg_pstate(cpu) - pid_calc(&cpu->pid, sample->busy_scaled); | 1246 | |
| 1247 | target = limits->no_turbo || limits->turbo_disabled ? | ||
| 1248 | cpu->pstate.max_pstate : cpu->pstate.turbo_pstate; | ||
| 1249 | target += target >> 2; | ||
| 1250 | target = mul_fp(target, busy_frac); | ||
| 1251 | if (target < cpu->pstate.min_pstate) | ||
| 1252 | target = cpu->pstate.min_pstate; | ||
| 1253 | |||
| 1254 | /* | ||
| 1255 | * If the average P-state during the previous cycle was higher than the | ||
| 1256 | * current target, add 50% of the difference to the target to reduce | ||
| 1257 | * possible performance oscillations and offset possible performance | ||
| 1258 | * loss related to moving the workload from one CPU to another within | ||
| 1259 | * a package/module. | ||
| 1260 | */ | ||
| 1261 | avg_pstate = get_avg_pstate(cpu); | ||
| 1262 | if (avg_pstate > target) | ||
| 1263 | target += (avg_pstate - target) >> 1; | ||
| 1264 | |||
| 1265 | return target; | ||
| 1246 | } | 1266 | } |
| 1247 | 1267 | ||
| 1248 | static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) | 1268 | static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) |
