|
@@ -53,6 +53,7 @@ struct sugov_cpu {
|
|
|
struct update_util_data update_util;
|
|
|
struct sugov_policy *sg_policy;
|
|
|
|
|
|
+ bool iowait_boost_pending;
|
|
|
unsigned long iowait_boost;
|
|
|
unsigned long iowait_boost_max;
|
|
|
u64 last_update;
|
|
@@ -169,30 +170,54 @@ static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
|
|
|
unsigned int flags)
|
|
|
{
|
|
|
if (flags & SCHED_CPUFREQ_IOWAIT) {
|
|
|
- sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
|
|
|
+ if (sg_cpu->iowait_boost_pending)
|
|
|
+ return;
|
|
|
+
|
|
|
+ sg_cpu->iowait_boost_pending = true;
|
|
|
+
|
|
|
+ if (sg_cpu->iowait_boost) {
|
|
|
+ sg_cpu->iowait_boost <<= 1;
|
|
|
+ if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max)
|
|
|
+ sg_cpu->iowait_boost = sg_cpu->iowait_boost_max;
|
|
|
+ } else {
|
|
|
+ sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min;
|
|
|
+ }
|
|
|
} else if (sg_cpu->iowait_boost) {
|
|
|
s64 delta_ns = time - sg_cpu->last_update;
|
|
|
|
|
|
/* Clear iowait_boost if the CPU apprears to have been idle. */
|
|
|
- if (delta_ns > TICK_NSEC)
|
|
|
+ if (delta_ns > TICK_NSEC) {
|
|
|
sg_cpu->iowait_boost = 0;
|
|
|
+ sg_cpu->iowait_boost_pending = false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util,
|
|
|
unsigned long *max)
|
|
|
{
|
|
|
- unsigned long boost_util = sg_cpu->iowait_boost;
|
|
|
- unsigned long boost_max = sg_cpu->iowait_boost_max;
|
|
|
+ unsigned long boost_util, boost_max;
|
|
|
|
|
|
- if (!boost_util)
|
|
|
+ if (!sg_cpu->iowait_boost)
|
|
|
return;
|
|
|
|
|
|
+ if (sg_cpu->iowait_boost_pending) {
|
|
|
+ sg_cpu->iowait_boost_pending = false;
|
|
|
+ } else {
|
|
|
+ sg_cpu->iowait_boost >>= 1;
|
|
|
+ if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) {
|
|
|
+ sg_cpu->iowait_boost = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ boost_util = sg_cpu->iowait_boost;
|
|
|
+ boost_max = sg_cpu->iowait_boost_max;
|
|
|
+
|
|
|
if (*util * boost_max < *max * boost_util) {
|
|
|
*util = boost_util;
|
|
|
*max = boost_max;
|
|
|
}
|
|
|
- sg_cpu->iowait_boost >>= 1;
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_NO_HZ_COMMON
|
|
@@ -264,6 +289,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
|
|
|
delta_ns = time - j_sg_cpu->last_update;
|
|
|
if (delta_ns > TICK_NSEC) {
|
|
|
j_sg_cpu->iowait_boost = 0;
|
|
|
+ j_sg_cpu->iowait_boost_pending = false;
|
|
|
continue;
|
|
|
}
|
|
|
if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL)
|