Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1257072
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 23/70] cpufreq: interactive: pin timers to associated CPU |
| Date | 2015-10-27 19:00 +0100 |
| Message-ID | <qogHo-8bo-11@gated-at.bofh.it> (permalink) |
| References | <qogo1-84h-5@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
From: Todd Poynor <toddpoynor@google.com>
Helps avoid waking up other CPUs to react to activity on the local CPU.
Change-Id: Ife272aaa7916894a437705d44521b1a1693fbe8e
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 106 +++++++++------------------------
1 file changed, 27 insertions(+), 79 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 16bd23b..e53eae2 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -42,8 +42,6 @@ struct cpufreq_interactive_cpuinfo {
int timer_idlecancel;
u64 time_in_idle;
u64 idle_exit_time;
- u64 timer_run_time;
- int idling;
u64 target_set_time;
u64 target_set_time_in_idle;
struct cpufreq_policy *policy;
@@ -109,6 +107,7 @@ struct cpufreq_governor cpufreq_gov_interactive = {
static void cpufreq_interactive_timer(unsigned long data)
{
+ u64 now;
unsigned int delta_idle;
unsigned int delta_time;
int cpu_load;
@@ -127,26 +126,11 @@ static void cpufreq_interactive_timer(unsigned long data)
if (!pcpu->governor_enabled)
goto exit;
- /*
- * Once pcpu->timer_run_time is updated to >= pcpu->idle_exit_time,
- * this lets idle exit know the current idle time sample has
- * been processed, and idle exit can generate a new sample and
- * re-arm the timer. This prevents a concurrent idle
- * exit on that CPU from writing a new set of info at the same time
- * the timer function runs (the timer function can't use that info
- * until more time passes).
- */
time_in_idle = pcpu->time_in_idle;
idle_exit_time = pcpu->idle_exit_time;
- now_idle = get_cpu_idle_time_us(data, &pcpu->timer_run_time);
- smp_wmb();
-
- /* If we raced with cancelling a timer, skip. */
- if (!idle_exit_time)
- goto exit;
-
+ now_idle = get_cpu_idle_time_us(data, &now);
delta_idle = (unsigned int)(now_idle - time_in_idle);
- delta_time = (unsigned int)(pcpu->timer_run_time - idle_exit_time);
+ delta_time = (unsigned int)(now - idle_exit_time);
/*
* If timer ran less than 1ms after short-term sample started, retry.
@@ -160,8 +144,7 @@ static void cpufreq_interactive_timer(unsigned long data)
cpu_load = 100 * (delta_time - delta_idle) / delta_time;
delta_idle = (unsigned int)(now_idle - pcpu->target_set_time_in_idle);
- delta_time = (unsigned int)(pcpu->timer_run_time -
- pcpu->target_set_time);
+ delta_time = (unsigned int)(now - pcpu->target_set_time);
if ((delta_time == 0) || (delta_idle > delta_time))
load_since_change = 0;
@@ -189,7 +172,7 @@ static void cpufreq_interactive_timer(unsigned long data)
if (pcpu->target_freq == hispeed_freq &&
new_freq > hispeed_freq &&
- pcpu->timer_run_time - pcpu->hispeed_validate_time
+ now - pcpu->hispeed_validate_time
< above_hispeed_delay_val) {
trace_cpufreq_interactive_notyet(data, cpu_load,
pcpu->target_freq,
@@ -202,7 +185,7 @@ static void cpufreq_interactive_timer(unsigned long data)
}
if (new_freq <= hispeed_freq)
- pcpu->hispeed_validate_time = pcpu->timer_run_time;
+ pcpu->hispeed_validate_time = now;
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
new_freq, CPUFREQ_RELATION_H,
@@ -219,8 +202,7 @@ static void cpufreq_interactive_timer(unsigned long data)
* floor frequency for the minimum sample time since last validated.
*/
if (new_freq < pcpu->floor_freq) {
- if (pcpu->timer_run_time - pcpu->floor_validate_time
- < min_sample_time) {
+ if (now - pcpu->floor_validate_time < min_sample_time) {
trace_cpufreq_interactive_notyet(data, cpu_load,
pcpu->target_freq, new_freq);
goto rearm;
@@ -228,7 +210,7 @@ static void cpufreq_interactive_timer(unsigned long data)
}
pcpu->floor_freq = new_freq;
- pcpu->floor_validate_time = pcpu->timer_run_time;
+ pcpu->floor_validate_time = now;
if (pcpu->target_freq == new_freq) {
trace_cpufreq_interactive_already(data, cpu_load,
@@ -239,7 +221,7 @@ static void cpufreq_interactive_timer(unsigned long data)
trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
new_freq);
pcpu->target_set_time_in_idle = now_idle;
- pcpu->target_set_time = pcpu->timer_run_time;
+ pcpu->target_set_time = now;
pcpu->target_freq = new_freq;
spin_lock_irqsave(&speedchange_cpumask_lock, flags);
@@ -258,23 +240,16 @@ rearm_if_notmax:
rearm:
if (!timer_pending(&pcpu->cpu_timer)) {
/*
- * If already at min: if that CPU is idle, don't set timer.
- * Else cancel the timer if that CPU goes idle. We don't
- * need to re-evaluate speed until the next idle exit.
+ * If already at min, cancel the timer if that CPU goes idle.
+ * We don't need to re-evaluate speed until the next idle exit.
*/
- if (pcpu->target_freq == pcpu->policy->min) {
- smp_rmb();
-
- if (pcpu->idling)
- goto exit;
-
+ if (pcpu->target_freq == pcpu->policy->min)
pcpu->timer_idlecancel = 1;
- }
pcpu->time_in_idle = get_cpu_idle_time_us(
data, &pcpu->idle_exit_time);
- mod_timer(&pcpu->cpu_timer,
- jiffies + usecs_to_jiffies(timer_rate));
+ mod_timer_pinned(&pcpu->cpu_timer,
+ jiffies + usecs_to_jiffies(timer_rate));
}
exit:
@@ -290,8 +265,6 @@ static void cpufreq_interactive_idle_start(void)
if (!pcpu->governor_enabled)
return;
- pcpu->idling = 1;
- smp_wmb();
pending = timer_pending(&pcpu->cpu_timer);
if (pcpu->target_freq != pcpu->policy->min) {
@@ -308,8 +281,9 @@ static void cpufreq_interactive_idle_start(void)
pcpu->time_in_idle = get_cpu_idle_time_us(
smp_processor_id(), &pcpu->idle_exit_time);
pcpu->timer_idlecancel = 0;
- mod_timer(&pcpu->cpu_timer,
- jiffies + usecs_to_jiffies(timer_rate));
+ mod_timer_pinned(
+ &pcpu->cpu_timer,
+ jiffies + usecs_to_jiffies(timer_rate));
}
#endif
} else {
@@ -321,12 +295,6 @@ static void cpufreq_interactive_idle_start(void)
*/
if (pending && pcpu->timer_idlecancel) {
del_timer(&pcpu->cpu_timer);
- /*
- * Ensure last timer run time is after current idle
- * sample start time, so next idle exit will always
- * start a new idle sampling period.
- */
- pcpu->idle_exit_time = 0;
pcpu->timer_idlecancel = 0;
}
}
@@ -341,29 +309,15 @@ static void cpufreq_interactive_idle_end(void)
if (!pcpu->governor_enabled)
return;
- pcpu->idling = 0;
- smp_wmb();
-
- /*
- * Arm the timer for 1-2 ticks later if not already, and if the timer
- * function has already processed the previous load sampling
- * interval. (If the timer is not pending but has not processed
- * the previous interval, it is probably racing with us on another
- * CPU. Let it compute load based on the previous sample and then
- * re-arm the timer for another interval when it's done, rather
- * than updating the interval start time to be "now", which doesn't
- * give the timer function enough time to make a decision on this
- * run.)
- */
- if (timer_pending(&pcpu->cpu_timer) == 0 &&
- pcpu->timer_run_time >= pcpu->idle_exit_time &&
- pcpu->governor_enabled) {
+ /* Arm the timer for 1-2 ticks later if not already. */
+ if (!timer_pending(&pcpu->cpu_timer)) {
pcpu->time_in_idle =
get_cpu_idle_time_us(smp_processor_id(),
&pcpu->idle_exit_time);
pcpu->timer_idlecancel = 0;
- mod_timer(&pcpu->cpu_timer,
- jiffies + usecs_to_jiffies(timer_rate));
+ mod_timer_pinned(
+ &pcpu->cpu_timer,
+ jiffies + usecs_to_jiffies(timer_rate));
}
}
@@ -673,6 +627,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
freq_table =
cpufreq_frequency_get_table(policy->cpu);
+ if (!hispeed_freq)
+ hispeed_freq = policy->max;
for_each_cpu(j, policy->cpus) {
pcpu = &per_cpu(cpuinfo, j);
@@ -689,11 +645,11 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->target_set_time;
pcpu->governor_enabled = 1;
smp_wmb();
+ pcpu->cpu_timer.expires =
+ jiffies + usecs_to_jiffies(timer_rate);
+ add_timer_on(&pcpu->cpu_timer, j);
}
- if (!hispeed_freq)
- hispeed_freq = policy->max;
-
/*
* Do not register the idle hook and create sysfs
* entries if we have already done so.
@@ -715,14 +671,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->governor_enabled = 0;
smp_wmb();
del_timer_sync(&pcpu->cpu_timer);
-
- /*
- * Reset idle exit time since we may cancel the timer
- * before it can run after the last idle exit time,
- * to avoid tripping the check in idle exit for a timer
- * that is trying to run.
- */
- pcpu->idle_exit_time = 0;
}
if (atomic_dec_return(&active_count) > 0)
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 01/70] cpufreq: interactive: New 'interactive' governor Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 57/70] cpufreq: interactive: fix compiling warnings Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 56/70] cpufreq: interactive: delete timers for GOV_START Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 41/70] cpufreq: interactive: fix race on governor start/stop Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 32/70] cpufreq: interactive: specify duration of CPU speed boost pulse Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 43/70] cpufreq: interactive: add io_is_busy interface Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 39/70] cpufreq: interactive: don't handle transition notification if not enabled Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 51/70] cpufreq: interactive: resched timer if max freq raised Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 09/70] cpufreq: interactive: Separate speed target revalidate time and initial set time Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 60/70] cpufreq: interactive: hold reference on global cpufreq kobject if needed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 24/70] cpufreq: interactive: use deferrable timer by default Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 61/70] cpufreq: interactive: restructure CPUFREQ_GOV_LIMITS Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 27/70] cpufreq: interactive: change speed according to current speed and target load Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 07/70] cpufreq: interactive: adjust code and documentation to match Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 29/70] cpufreq: interactive: allow arbitrary speed / target load mappings Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 48/70] cpufreq: interactive: reduce chance of zero time delta on load eval Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 64/70] cpufreq: interactive: prevents the frequency to directly raise above the hispeed_freq from a lower frequency. Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 65/70] cpufreq: interactive: make common_tunables static Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 69/70] cpufreq: interactive: Don't set floor_validate_time during boost Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 37/70] cpufreq: interactive: default go_hispeed_load 99%, doc updates Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 58/70] cpufreq: interactive: fix NULL pointer dereference at sysfs ops Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 66/70] cpufreq: interactive: Fix compile errors in accordance with changes from 3.14 to 3.18 Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 17/70] cpufreq: interactive: take idle notifications only when active Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 35/70] cpufreq: interactive: fix racy timer stopping Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 67/70] cpufreq: interactive: Put global cpufreq kobject on failure Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 70/70] cpufreq: interactive: Round up timer_rate to match jiffy Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 20/70] cpufreq: interactive: remove input_boost handling Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 12/70] cpufreq: interactive: Add sysfs boost interface for hints from userspace Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 22/70] cpufreq: interactive: run at fraction of hispeed_freq when load is low Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 68/70] subsystem: CPU FREQUENCY DRIVERS- Set cpu_load calculation on current frequency Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 13/70] cpufreq: interactive: set floor for boosted speed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 55/70] cpufreq: Interactive: Implement per policy instances of governor Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 52/70] cpufreq: interactive: fix show_target_loads and show_above_hispeed_delay Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 10/70] cpufreq: interactive: Boost frequency on touchscreen input Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:40 +0100
[PATCH 62/70] cpufreq: interactive: turn boost_pulse off on boost off Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 59/70] cpufreq: interactive: Use generic get_cpu_idle_time() from cpufreq.c Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 54/70] cpufreq: interactive: Move definition of cpufreq_gov_interactive downwards Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 53/70] cpufreq: interactive: Remove unnecessary cpu_online() check Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 25/70] cpufreq: interactive: kick timer on idle exit past expiry Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 47/70] cpufreq: interactive: handle errors from cpufreq_frequency_table_target Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 63/70] cpufreq: interactive: remove compilation error from commit 49cc72365fb7ee87762a7ccc6a32ef68627216c5 Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 44/70] cpufreq: interactive: fix crash on error paths in get_tokenized_data Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 50/70] cpufreq: interactive: fix race on cpufreq TRANSITION notifier Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 49/70] cpufreq: interactive: avoid underflow on active time calculation Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 45/70] cpufreq: interactive: base above_hispeed_delay on target freq, not current Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 46/70] cpufreq: interactive: fix uninitialized spinlock Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 18:50 +0100
[PATCH 34/70] cpufreq: interactive: fix boosting logic Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 38/70] cpufreq: interactive: init default values at compile time Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 16/70] cpufreq: interactive: restart above_hispeed_delay at each hispeed load Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 28/70] cpufreq: interactive: apply above_hispeed_delay to each step above hispeed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 23/70] cpufreq: interactive: pin timers to associated CPU Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 18/70] cpufreq: interactive: keep freezer happy when not current governor Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 21/70] cpufreq: interactive: always limit initial speed bump to hispeed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 36/70] cpufreq: interactive: fix race on timer restart on governor start Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 19/70] cpufreq: interactive: handle speed up and down in the realtime task Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 42/70] cpufreq: interactive: allow arbitrary speed / delay mappings Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 26/70] cpufreq: interactive: trace actual speed in target speed decisions Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 30/70] cpufreq: interactive: remove load since last speed change Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 40/70] cpufreq: interactive: fix deadlock on spinlock in timer Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 33/70] cpufreq: interactive: add timer slack to limit idle at speed > min Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 31/70] cpufreq: interactive: adjust load for changes in speed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:00 +0100
[PATCH 04/70] cpufreq: interactive: set at least hispeed when above hispeed load Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 02/70] cpufreq interactive governor: event tracing Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 11/70] cpufreq: interactive: remove unused target_validate_time_in_idle Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 05/70] cpufreq: interactive: don't drop speed if recently at higher load Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 06/70] cpufreq: interactive: configurable delay before raising above hispeed Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 08/70] cpufreq: interactive: base hispeed bump on target freq, not actual Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 15/70] cpufreq-interactive: Compile fixup Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
[PATCH 14/70] cpufreq: interactive: add boost pulse interface Bálint Czobor <czoborbalint@gmail.com> - 2015-10-27 19:10 +0100
Re: [PATCH 01/70] cpufreq: interactive: New 'interactive' governor "Rafael J. Wysocki" <rjw@rjwysocki.net> - 2015-10-28 01:40 +0100
Re: [PATCH 01/70] cpufreq: interactive: New 'interactive' governor Viresh Kumar <viresh.kumar@linaro.org> - 2015-10-28 04:10 +0100
Re: [PATCH 01/70] cpufreq: interactive: New 'interactive' governor Viresh Kumar <viresh.kumar@linaro.org> - 2015-10-29 02:50 +0100
csiph-web