For non-HWP systems, rework iowait boost to be linear and add the sysfs knob iowait_boost_cap to limit the maximum boost in 8 steps. I don't see a good way to translate this to HWP, as the boost applied isn't as static as it is for non-HWP, but there is already the dynamic_hwp_boost sysfs to enable/disable completely. Signed-off-by: Christian Loehle <christian.loehle@xxxxxxx> --- drivers/cpufreq/intel_pstate.c | 39 ++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index c0278d023cfc..6882d8c74e61 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -183,6 +183,7 @@ struct global_params { bool turbo_disabled; int max_perf_pct; int min_perf_pct; + unsigned int iowait_boost_cap; }; /** @@ -1444,6 +1445,30 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct kobj_attribute *b, return count; } +static ssize_t store_iowait_boost_cap(struct kobject *a, struct kobj_attribute *b, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + ret = sscanf(buf, "%u", &input); + if (ret != 1) + return -EINVAL; + + mutex_lock(&intel_pstate_driver_lock); + + if (!intel_pstate_driver) { + mutex_unlock(&intel_pstate_driver_lock); + return -EAGAIN; + } + + global.iowait_boost_cap = clamp_t(int, input, 0, 8); + + mutex_unlock(&intel_pstate_driver_lock); + + return count; +} + static ssize_t show_hwp_dynamic_boost(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -1497,6 +1522,7 @@ static ssize_t store_energy_efficiency(struct kobject *a, struct kobj_attribute show_one(max_perf_pct, max_perf_pct); show_one(min_perf_pct, min_perf_pct); +show_one(iowait_boost_cap, iowait_boost_cap); define_one_global_rw(status); define_one_global_rw(no_turbo); @@ -1506,6 +1532,7 @@ define_one_global_ro(turbo_pct); define_one_global_ro(num_pstates); define_one_global_rw(hwp_dynamic_boost); define_one_global_rw(energy_efficiency); +define_one_global_rw(iowait_boost_cap); static struct attribute *intel_pstate_attributes[] = { &status.attr, @@ -1562,6 +1589,9 @@ static void __init intel_pstate_sysfs_expose_params(void) rc = sysfs_create_file(intel_pstate_kobject, &energy_efficiency.attr); WARN_ON(rc); } + + rc = sysfs_create_file(intel_pstate_kobject, &iowait_boost_cap.attr); + WARN_ON(rc); } static void __init intel_pstate_sysfs_remove(void) @@ -2322,18 +2352,23 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, if (delta_ns > TICK_NSEC) { cpu->iowait_boost = ONE_EIGHTH_FP; } else if (cpu->iowait_boost >= ONE_EIGHTH_FP) { - cpu->iowait_boost <<= 1; + cpu->iowait_boost += ONE_EIGHTH_FP; if (cpu->iowait_boost > int_tofp(1)) cpu->iowait_boost = int_tofp(1); } else { cpu->iowait_boost = ONE_EIGHTH_FP; } + if (cpu->iowait_boost > global.iowait_boost_cap * ONE_EIGHTH_FP) + cpu->iowait_boost = global.iowait_boost_cap * ONE_EIGHTH_FP; } else if (cpu->iowait_boost) { /* Clear iowait_boost if the CPU may have been idle. */ if (delta_ns > TICK_NSEC) cpu->iowait_boost = 0; - else + else { cpu->iowait_boost >>= 1; + if (cpu->iowait_boost < ONE_EIGHTH_FP) + cpu->iowait_boost = 0; + } } cpu->last_update = time; delta_ns = time - cpu->sample.time; -- 2.25.1