summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/intel_pstate.c
diff options
context:
space:
mode:
authorPhilippe Longepe2015-12-04 17:40:35 +0100
committerRafael J. Wysocki2015-12-10 01:17:40 +0100
commit63d1d656a5232f2f189b217b50542eadcf9d74ae (patch)
tree92372ee9b437e67a6a49c1749dde06b1fb5b3564 /drivers/cpufreq/intel_pstate.c
parentcpufreq: intel_pstate: Account for non C0 time (diff)
downloadkernel-qcow2-linux-63d1d656a5232f2f189b217b50542eadcf9d74ae.tar.gz
kernel-qcow2-linux-63d1d656a5232f2f189b217b50542eadcf9d74ae.tar.xz
kernel-qcow2-linux-63d1d656a5232f2f189b217b50542eadcf9d74ae.zip
cpufreq: intel_pstate: Account for IO wait time
In cases where we have many IOs, the global load becomes low and the load algorithm will decrease the requested P-State. Because of that, the IOs overheads will increase and impact the IO performances. To improve IO bound work, we can count the io-wait time as busy time in calculating CPU busy. This change uses get_cpu_iowait_time_us() to obtain the IO wait time value and converts time into number of cycles spent waiting on IO at the TSC rate. At the moment, this trick is only used for Atom. Signed-off-by: Philippe Longepe <philippe.longepe@intel.com> Signed-off-by: Stephane Gasparini <stephane.gasparini@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r--drivers/cpufreq/intel_pstate.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 8bfebaeda2dd..efc581392bd1 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -113,6 +113,7 @@ struct cpudata {
u64 prev_aperf;
u64 prev_mperf;
u64 prev_tsc;
+ u64 prev_cummulative_iowait;
struct sample sample;
};
@@ -933,22 +934,39 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu)
static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu)
{
struct sample *sample = &cpu->sample;
+ u64 cummulative_iowait, delta_iowait_us;
+ u64 delta_iowait_mperf;
+ u64 mperf, now;
int32_t cpu_load;
+ cummulative_iowait = get_cpu_iowait_time_us(cpu->cpu, &now);
+
+ /*
+ * Convert iowait time into number of IO cycles spent at max_freq.
+ * IO is considered as busy only for the cpu_load algorithm. For
+ * performance this is not needed since we always try to reach the
+ * maximum P-State, so we are already boosting the IOs.
+ */
+ delta_iowait_us = cummulative_iowait - cpu->prev_cummulative_iowait;
+ delta_iowait_mperf = div64_u64(delta_iowait_us * cpu->pstate.scaling *
+ cpu->pstate.max_pstate, MSEC_PER_SEC);
+
+ mperf = cpu->sample.mperf + delta_iowait_mperf;
+ cpu->prev_cummulative_iowait = cummulative_iowait;
+
+
/*
* The load can be estimated as the ratio of the mperf counter
* running at a constant frequency during active periods
* (C0) and the time stamp counter running at the same frequency
* also during C-states.
*/
- cpu_load = div64_u64(int_tofp(100) * sample->mperf, sample->tsc);
-
+ cpu_load = div64_u64(int_tofp(100) * mperf, sample->tsc);
cpu->sample.busy_scaled = cpu_load;
return cpu->pstate.current_pstate - pid_calc(&cpu->pid, cpu_load);
}
-
static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu)
{
int32_t core_busy, max_pstate, current_pstate, sample_ratio;