Loading drivers/cpufreq/cpu-boost.c +11 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,17 @@ static int boost_mig_sync_thread(void *data) /* Force policy re-evaluation to trigger adjust notifier. */ get_online_cpus(); if (cpu_online(src_cpu)) /* * Send an unchanged policy update to the source * CPU. Even though the policy isn't changed from * its existing boosted or non-boosted state * notifying the source CPU will let the governor * know a boost happened on another CPU and that it * should re-evaluate the frequency at the next timer * event without interference from a min sample time. */ cpufreq_update_policy(src_cpu); if (cpu_online(dest_cpu)) { cpufreq_update_policy(dest_cpu); queue_delayed_work_on(dest_cpu, cpu_boost_wq, Loading drivers/cpufreq/cpufreq_interactive.c +46 −12 Original line number Diff line number Diff line Loading @@ -55,8 +55,11 @@ struct cpufreq_interactive_cpuinfo { struct rw_semaphore enable_sem; int governor_enabled; int prev_load; bool limits_changed; }; #define MIN_TIMER_JIFFIES 1UL static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo); /* realtime thread handles frequency scaling */ Loading Loading @@ -174,11 +177,15 @@ static void cpufreq_interactive_timer_resched( * The cpu_timer and cpu_slack_timer must be deactivated when calling this * function. */ static void cpufreq_interactive_timer_start(int cpu) static void cpufreq_interactive_timer_start(int cpu, int time_override) { struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); unsigned long expires = jiffies + usecs_to_jiffies(timer_rate); unsigned long flags; unsigned long expires; if (time_override) expires = jiffies + time_override; else expires = jiffies + usecs_to_jiffies(timer_rate); pcpu->cpu_timer.expires = expires; add_timer_on(&pcpu->cpu_timer, cpu); Loading Loading @@ -448,6 +455,10 @@ static void cpufreq_interactive_timer(unsigned long data) else mod_min_sample_time = min_sample_time; if (pcpu->limits_changed) { mod_min_sample_time = 0; pcpu->limits_changed = false; } if (new_freq < pcpu->floor_freq) { if (now - pcpu->floor_validate_time < mod_min_sample_time) { trace_cpufreq_interactive_notyet( Loading Loading @@ -1192,6 +1203,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, unsigned int j; struct cpufreq_interactive_cpuinfo *pcpu; struct cpufreq_frequency_table *freq_table; unsigned long expire_time; switch (event) { case CPUFREQ_GOV_START: Loading @@ -1218,7 +1230,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, down_write(&pcpu->enable_sem); del_timer_sync(&pcpu->cpu_timer); del_timer_sync(&pcpu->cpu_slack_timer); cpufreq_interactive_timer_start(j); cpufreq_interactive_timer_start(j, 0); pcpu->governor_enabled = 1; up_write(&pcpu->enable_sem); } Loading Loading @@ -1296,18 +1308,40 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, /* update target_freq firstly */ if (policy->max < pcpu->target_freq) pcpu->target_freq = policy->max; else if (policy->min > pcpu->target_freq) pcpu->target_freq = policy->min; /* Reschedule timer. * Delete the timers, else the timer callback may * return without re-arm the timer when failed * acquire the semaphore. This race may cause timer * stopped unexpectedly. /* * Delete and reschedule timer. * Else the timer callback may return without * re-arming the timer when it fails to acquire * the semaphore. This race condition may cause the * timer to stop unexpectedly. */ del_timer_sync(&pcpu->cpu_timer); del_timer_sync(&pcpu->cpu_slack_timer); cpufreq_interactive_timer_start(j); if (policy->min >= pcpu->target_freq) { pcpu->target_freq = policy->min; /* * Reschedule timer. * The governor needs more time to evaluate * the load after changing policy parameters. */ cpufreq_interactive_timer_start(j, 0); } else { /* * Reschedule timer with variable duration. * No boost was applied so the governor * doesn't need extra time to evaluate load. * The timer can be set to fire quicker if it * was already going to expire soon. */ expire_time = pcpu->cpu_timer.expires - jiffies; expire_time = min(usecs_to_jiffies(timer_rate), expire_time); expire_time = max(MIN_TIMER_JIFFIES, expire_time); cpufreq_interactive_timer_start(j, expire_time); } pcpu->limits_changed = true; up_write(&pcpu->enable_sem); } break; Loading Loading
drivers/cpufreq/cpu-boost.c +11 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,17 @@ static int boost_mig_sync_thread(void *data) /* Force policy re-evaluation to trigger adjust notifier. */ get_online_cpus(); if (cpu_online(src_cpu)) /* * Send an unchanged policy update to the source * CPU. Even though the policy isn't changed from * its existing boosted or non-boosted state * notifying the source CPU will let the governor * know a boost happened on another CPU and that it * should re-evaluate the frequency at the next timer * event without interference from a min sample time. */ cpufreq_update_policy(src_cpu); if (cpu_online(dest_cpu)) { cpufreq_update_policy(dest_cpu); queue_delayed_work_on(dest_cpu, cpu_boost_wq, Loading
drivers/cpufreq/cpufreq_interactive.c +46 −12 Original line number Diff line number Diff line Loading @@ -55,8 +55,11 @@ struct cpufreq_interactive_cpuinfo { struct rw_semaphore enable_sem; int governor_enabled; int prev_load; bool limits_changed; }; #define MIN_TIMER_JIFFIES 1UL static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo); /* realtime thread handles frequency scaling */ Loading Loading @@ -174,11 +177,15 @@ static void cpufreq_interactive_timer_resched( * The cpu_timer and cpu_slack_timer must be deactivated when calling this * function. */ static void cpufreq_interactive_timer_start(int cpu) static void cpufreq_interactive_timer_start(int cpu, int time_override) { struct cpufreq_interactive_cpuinfo *pcpu = &per_cpu(cpuinfo, cpu); unsigned long expires = jiffies + usecs_to_jiffies(timer_rate); unsigned long flags; unsigned long expires; if (time_override) expires = jiffies + time_override; else expires = jiffies + usecs_to_jiffies(timer_rate); pcpu->cpu_timer.expires = expires; add_timer_on(&pcpu->cpu_timer, cpu); Loading Loading @@ -448,6 +455,10 @@ static void cpufreq_interactive_timer(unsigned long data) else mod_min_sample_time = min_sample_time; if (pcpu->limits_changed) { mod_min_sample_time = 0; pcpu->limits_changed = false; } if (new_freq < pcpu->floor_freq) { if (now - pcpu->floor_validate_time < mod_min_sample_time) { trace_cpufreq_interactive_notyet( Loading Loading @@ -1192,6 +1203,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, unsigned int j; struct cpufreq_interactive_cpuinfo *pcpu; struct cpufreq_frequency_table *freq_table; unsigned long expire_time; switch (event) { case CPUFREQ_GOV_START: Loading @@ -1218,7 +1230,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, down_write(&pcpu->enable_sem); del_timer_sync(&pcpu->cpu_timer); del_timer_sync(&pcpu->cpu_slack_timer); cpufreq_interactive_timer_start(j); cpufreq_interactive_timer_start(j, 0); pcpu->governor_enabled = 1; up_write(&pcpu->enable_sem); } Loading Loading @@ -1296,18 +1308,40 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, /* update target_freq firstly */ if (policy->max < pcpu->target_freq) pcpu->target_freq = policy->max; else if (policy->min > pcpu->target_freq) pcpu->target_freq = policy->min; /* Reschedule timer. * Delete the timers, else the timer callback may * return without re-arm the timer when failed * acquire the semaphore. This race may cause timer * stopped unexpectedly. /* * Delete and reschedule timer. * Else the timer callback may return without * re-arming the timer when it fails to acquire * the semaphore. This race condition may cause the * timer to stop unexpectedly. */ del_timer_sync(&pcpu->cpu_timer); del_timer_sync(&pcpu->cpu_slack_timer); cpufreq_interactive_timer_start(j); if (policy->min >= pcpu->target_freq) { pcpu->target_freq = policy->min; /* * Reschedule timer. * The governor needs more time to evaluate * the load after changing policy parameters. */ cpufreq_interactive_timer_start(j, 0); } else { /* * Reschedule timer with variable duration. * No boost was applied so the governor * doesn't need extra time to evaluate load. * The timer can be set to fire quicker if it * was already going to expire soon. */ expire_time = pcpu->cpu_timer.expires - jiffies; expire_time = min(usecs_to_jiffies(timer_rate), expire_time); expire_time = max(MIN_TIMER_JIFFIES, expire_time); cpufreq_interactive_timer_start(j, expire_time); } pcpu->limits_changed = true; up_write(&pcpu->enable_sem); } break; Loading