diff options
| -rw-r--r-- | drivers/cpufreq/cpufreq_interactive.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 0237462223b2..155f5bd9b4f7 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -53,6 +53,7 @@ struct cpufreq_interactive_cpuinfo { u64 pol_hispeed_val_time; /* policy hispeed_validate_time */ u64 loc_hispeed_val_time; /* per-cpu hispeed_validate_time */ u64 max_freq_hyst_start_time; + unsigned int min_freq; struct rw_semaphore enable_sem; bool reject_notification; int governor_enabled; @@ -193,7 +194,8 @@ static inline int set_window_helper( usecs_to_jiffies(tunables->timer_rate)); } -static void cpufreq_interactive_timer_resched(unsigned long cpu) +static void cpufreq_interactive_timer_resched(unsigned long cpu, + bool slack_only) { struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); struct cpufreq_interactive_tunables *tunables = @@ -202,16 +204,18 @@ static void cpufreq_interactive_timer_resched(unsigned long cpu) unsigned long flags; spin_lock_irqsave(&pcpu->load_lock, flags); - pcpu->time_in_idle = - get_cpu_idle_time(smp_processor_id(), + expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables); + if (!slack_only) { + pcpu->time_in_idle = + get_cpu_idle_time(smp_processor_id(), &pcpu->time_in_idle_timestamp, tunables->io_is_busy); - pcpu->cputime_speedadj = 0; - pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp; - expires = round_to_nw_start(pcpu->last_evaluated_jiffy, tunables); - del_timer(&pcpu->cpu_timer); - pcpu->cpu_timer.expires = expires; - add_timer_on(&pcpu->cpu_timer, cpu); + pcpu->cputime_speedadj = 0; + pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp; + del_timer(&pcpu->cpu_timer); + pcpu->cpu_timer.expires = expires; + add_timer_on(&pcpu->cpu_timer, cpu); + } if (tunables->timer_slack_val >= 0 && pcpu->target_freq > pcpu->policy->min) { @@ -576,7 +580,7 @@ static void cpufreq_interactive_timer(unsigned long data) rearm: if (!timer_pending(&pcpu->cpu_timer)) - cpufreq_interactive_timer_resched(data); + cpufreq_interactive_timer_resched(data, false); exit: up_read(&pcpu->enable_sem); @@ -597,7 +601,7 @@ static void cpufreq_interactive_idle_end(void) /* Arm the timer for 1-2 ticks later if not already. */ if (!timer_pending(&pcpu->cpu_timer)) { - cpufreq_interactive_timer_resched(smp_processor_id()); + cpufreq_interactive_timer_resched(smp_processor_id(), false); } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) { del_timer(&pcpu->cpu_timer); del_timer(&pcpu->cpu_slack_timer); @@ -1615,6 +1619,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, pcpu->loc_floor_val_time = pcpu->pol_floor_val_time; pcpu->pol_hispeed_val_time = pcpu->pol_floor_val_time; pcpu->loc_hispeed_val_time = pcpu->pol_floor_val_time; + pcpu->min_freq = policy->min; pcpu->reject_notification = true; down_write(&pcpu->enable_sem); del_timer_sync(&pcpu->cpu_timer); @@ -1668,6 +1673,11 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, pcpu->target_freq = policy->min; spin_unlock_irqrestore(&pcpu->target_freq_lock, flags); + + if (policy->min < pcpu->min_freq) + cpufreq_interactive_timer_resched(j, true); + pcpu->min_freq = policy->min; + up_read(&pcpu->enable_sem); } break; |
