|
@@ -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;
|