diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-02-07 06:51:04 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2019-02-18 05:34:32 -0500 |
| commit | b8bd1581aa6110eb234c0d424eccd3f32d7317e6 (patch) | |
| tree | 3f713517190e48b5b5d33abc51e5523456ffde87 | |
| parent | a8e1942d97dcc44d1425807c71a4252f9e3b53b6 (diff) | |
cpufreq: intel_pstate: Rework iowait boosting to be less aggressive
The current iowait boosting mechanism in intel_pstate_update_util()
is quite aggressive, as it goes to the maximum P-state right away,
and may cause excessive amounts of energy to be used, which is not
desirable and arguably isn't necessary too.
Follow commit a5a0809bc58e ("cpufreq: schedutil: Make iowait boost
more energy efficient") that reworked the analogous iowait boost
mechanism in the schedutil governor and make the iowait boosting
in intel_pstate_update_util() work along the same lines.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9a6cb3a1be50..002f5169d4eb 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -50,6 +50,8 @@ | |||
| 50 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 50 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
| 51 | #define fp_toint(X) ((X) >> FRAC_BITS) | 51 | #define fp_toint(X) ((X) >> FRAC_BITS) |
| 52 | 52 | ||
| 53 | #define ONE_EIGHTH_FP ((int64_t)1 << (FRAC_BITS - 3)) | ||
| 54 | |||
| 53 | #define EXT_BITS 6 | 55 | #define EXT_BITS 6 |
| 54 | #define EXT_FRAC_BITS (EXT_BITS + FRAC_BITS) | 56 | #define EXT_FRAC_BITS (EXT_BITS + FRAC_BITS) |
| 55 | #define fp_ext_toint(X) ((X) >> EXT_FRAC_BITS) | 57 | #define fp_ext_toint(X) ((X) >> EXT_FRAC_BITS) |
| @@ -1671,17 +1673,14 @@ static inline int32_t get_avg_pstate(struct cpudata *cpu) | |||
| 1671 | static inline int32_t get_target_pstate(struct cpudata *cpu) | 1673 | static inline int32_t get_target_pstate(struct cpudata *cpu) |
| 1672 | { | 1674 | { |
| 1673 | struct sample *sample = &cpu->sample; | 1675 | struct sample *sample = &cpu->sample; |
| 1674 | int32_t busy_frac, boost; | 1676 | int32_t busy_frac; |
| 1675 | int target, avg_pstate; | 1677 | int target, avg_pstate; |
| 1676 | 1678 | ||
| 1677 | busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift, | 1679 | busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift, |
| 1678 | sample->tsc); | 1680 | sample->tsc); |
| 1679 | 1681 | ||
| 1680 | boost = cpu->iowait_boost; | 1682 | if (busy_frac < cpu->iowait_boost) |
| 1681 | cpu->iowait_boost >>= 1; | 1683 | busy_frac = cpu->iowait_boost; |
| 1682 | |||
| 1683 | if (busy_frac < boost) | ||
| 1684 | busy_frac = boost; | ||
| 1685 | 1684 | ||
| 1686 | sample->busy_scaled = busy_frac * 100; | 1685 | sample->busy_scaled = busy_frac * 100; |
| 1687 | 1686 | ||
| @@ -1758,29 +1757,30 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, | |||
| 1758 | if (smp_processor_id() != cpu->cpu) | 1757 | if (smp_processor_id() != cpu->cpu) |
| 1759 | return; | 1758 | return; |
| 1760 | 1759 | ||
| 1760 | delta_ns = time - cpu->last_update; | ||
| 1761 | if (flags & SCHED_CPUFREQ_IOWAIT) { | 1761 | if (flags & SCHED_CPUFREQ_IOWAIT) { |
| 1762 | cpu->iowait_boost = int_tofp(1); | 1762 | /* Start over if the CPU may have been idle. */ |
| 1763 | cpu->last_update = time; | 1763 | if (delta_ns > TICK_NSEC) { |
| 1764 | /* | 1764 | cpu->iowait_boost = ONE_EIGHTH_FP; |
| 1765 | * The last time the busy was 100% so P-state was max anyway | 1765 | } else if (cpu->iowait_boost) { |
| 1766 | * so avoid overhead of computation. | 1766 | cpu->iowait_boost <<= 1; |
| 1767 | */ | 1767 | if (cpu->iowait_boost > int_tofp(1)) |
| 1768 | if (fp_toint(cpu->sample.busy_scaled) == 100) | 1768 | cpu->iowait_boost = int_tofp(1); |
| 1769 | return; | 1769 | } else { |
| 1770 | 1770 | cpu->iowait_boost = ONE_EIGHTH_FP; | |
| 1771 | goto set_pstate; | 1771 | } |
| 1772 | } else if (cpu->iowait_boost) { | 1772 | } else if (cpu->iowait_boost) { |
| 1773 | /* Clear iowait_boost if the CPU may have been idle. */ | 1773 | /* Clear iowait_boost if the CPU may have been idle. */ |
| 1774 | delta_ns = time - cpu->last_update; | ||
| 1775 | if (delta_ns > TICK_NSEC) | 1774 | if (delta_ns > TICK_NSEC) |
| 1776 | cpu->iowait_boost = 0; | 1775 | cpu->iowait_boost = 0; |
| 1776 | else | ||
| 1777 | cpu->iowait_boost >>= 1; | ||
| 1777 | } | 1778 | } |
| 1778 | cpu->last_update = time; | 1779 | cpu->last_update = time; |
| 1779 | delta_ns = time - cpu->sample.time; | 1780 | delta_ns = time - cpu->sample.time; |
| 1780 | if ((s64)delta_ns < INTEL_PSTATE_SAMPLING_INTERVAL) | 1781 | if ((s64)delta_ns < INTEL_PSTATE_SAMPLING_INTERVAL) |
| 1781 | return; | 1782 | return; |
| 1782 | 1783 | ||
| 1783 | set_pstate: | ||
| 1784 | if (intel_pstate_sample(cpu, time)) | 1784 | if (intel_pstate_sample(cpu, time)) |
| 1785 | intel_pstate_adjust_pstate(cpu); | 1785 | intel_pstate_adjust_pstate(cpu); |
| 1786 | } | 1786 | } |
