Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1257089
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 33/70] cpufreq: interactive: add timer slack to limit idle at speed > min |
| Date | 2015-10-27 19:00 +0100 |
| Message-ID | <qogHp-8bo-57@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>
Always use deferrable timer for load sampling.
Set a non-deferrable timer to an additional slack time to allow prior to
waking up from idle to drop speed when not at minimum speed. Slack value
-1 avoids wakeups to drop speed. Default is 80ms.
Remove the governidle module param and its timer management in idle. For
platforms on which holding speed above mimum in idle costs power, use the
new timer slack to select how long to wait before waking up to drop speed.
Change-Id: I270b3980667e2c70a68e5bff534124b4411dbad5
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 101 ++++++++++++++++++++-------------
1 file changed, 61 insertions(+), 40 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 8b44a82..690be16 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -40,7 +40,7 @@ static atomic_t active_count = ATOMIC_INIT(0);
struct cpufreq_interactive_cpuinfo {
struct timer_list cpu_timer;
- int timer_idlecancel;
+ struct timer_list cpu_slack_timer;
spinlock_t load_lock; /* protects the next 4 fields */
u64 time_in_idle;
u64 time_in_idle_timestamp;
@@ -102,10 +102,12 @@ static int boostpulse_duration_val = DEFAULT_MIN_SAMPLE_TIME;
/* End time of boost pulse in ktime converted to usecs */
static u64 boostpulse_endtime;
-static bool governidle;
-module_param(governidle, bool, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(governidle,
- "Set to 1 to wake up CPUs from idle to reduce speed (default 0)");
+/*
+ * Max additional time to wait in idle, beyond timer_rate, at speeds above
+ * minimum before wakeup to reduce speed, or -1 if unnecessary.
+ */
+#define DEFAULT_TIMER_SLACK (4 * DEFAULT_TIMER_RATE)
+static int timer_slack_val = DEFAULT_TIMER_SLACK;
static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
unsigned int event);
@@ -123,8 +125,14 @@ struct cpufreq_governor cpufreq_gov_interactive = {
static void cpufreq_interactive_timer_resched(
struct cpufreq_interactive_cpuinfo *pcpu)
{
- mod_timer_pinned(&pcpu->cpu_timer,
- jiffies + usecs_to_jiffies(timer_rate));
+ unsigned long expires = jiffies + usecs_to_jiffies(timer_rate);
+
+ mod_timer_pinned(&pcpu->cpu_timer, expires);
+ if (timer_slack_val >= 0 && pcpu->target_freq > pcpu->policy->min) {
+ expires += usecs_to_jiffies(timer_slack_val);
+ mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
+ }
+
spin_lock(&pcpu->load_lock);
pcpu->time_in_idle =
get_cpu_idle_time_us(smp_processor_id(),
@@ -368,17 +376,8 @@ rearm_if_notmax:
goto exit;
rearm:
- if (!timer_pending(&pcpu->cpu_timer)) {
- /*
- * If governing speed in idle and 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 (governidle && pcpu->target_freq == pcpu->policy->min)
- pcpu->timer_idlecancel = 1;
-
+ if (!timer_pending(&pcpu->cpu_timer))
cpufreq_interactive_timer_resched(pcpu);
- }
exit:
return;
@@ -404,21 +403,8 @@ static void cpufreq_interactive_idle_start(void)
* min indefinitely. This should probably be a quirk of
* the CPUFreq driver.
*/
- if (!pending) {
- pcpu->timer_idlecancel = 0;
+ if (!pending)
cpufreq_interactive_timer_resched(pcpu);
- }
- } else if (governidle) {
- /*
- * If at min speed and entering idle after load has
- * already been evaluated, and a timer has been set just in
- * case the CPU suddenly goes busy, cancel that timer. The
- * CPU didn't go busy; we'll recheck things upon idle exit.
- */
- if (pending && pcpu->timer_idlecancel) {
- del_timer(&pcpu->cpu_timer);
- pcpu->timer_idlecancel = 0;
- }
}
}
@@ -433,11 +419,10 @@ static void cpufreq_interactive_idle_end(void)
/* Arm the timer for 1-2 ticks later if not already. */
if (!timer_pending(&pcpu->cpu_timer)) {
- pcpu->timer_idlecancel = 0;
cpufreq_interactive_timer_resched(pcpu);
- } else if (!governidle &&
- time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
+ } else if (time_after_eq(jiffies, pcpu->cpu_timer.expires)) {
del_timer(&pcpu->cpu_timer);
+ del_timer(&pcpu->cpu_slack_timer);
cpufreq_interactive_timer(smp_processor_id());
}
}
@@ -747,6 +732,29 @@ static ssize_t store_timer_rate(struct kobject *kobj,
static struct global_attr timer_rate_attr = __ATTR(timer_rate, 0644,
show_timer_rate, store_timer_rate);
+static ssize_t show_timer_slack(
+ struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", timer_slack_val);
+}
+
+static ssize_t store_timer_slack(
+ struct kobject *kobj, struct attribute *attr, const char *buf,
+ size_t count)
+{
+ int ret;
+ unsigned long val;
+
+ ret = kstrtol(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ timer_slack_val = val;
+ return count;
+}
+
+define_one_global_rw(timer_slack);
+
static ssize_t show_boost(struct kobject *kobj, struct attribute *attr,
char *buf)
{
@@ -826,6 +834,7 @@ static struct attribute *interactive_attributes[] = {
&above_hispeed_delay.attr,
&min_sample_time_attr.attr,
&timer_rate_attr.attr,
+ &timer_slack.attr,
&boost.attr,
&boostpulse.attr,
&boostpulse_duration.attr,
@@ -876,6 +885,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
hispeed_freq = policy->max;
for_each_cpu(j, policy->cpus) {
+ unsigned long expires;
+
pcpu = &per_cpu(cpuinfo, j);
pcpu->policy = policy;
pcpu->target_freq = policy->cur;
@@ -887,9 +898,15 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->floor_validate_time;
pcpu->governor_enabled = 1;
smp_wmb();
- pcpu->cpu_timer.expires =
- jiffies + usecs_to_jiffies(timer_rate);
+ expires = jiffies + usecs_to_jiffies(timer_rate);
+ pcpu->cpu_timer.expires = expires;
add_timer_on(&pcpu->cpu_timer, j);
+
+ if (timer_slack_val >= 0) {
+ expires += usecs_to_jiffies(timer_slack_val);
+ pcpu->cpu_slack_timer.expires = expires;
+ add_timer_on(&pcpu->cpu_slack_timer, j);
+ }
}
/*
@@ -915,6 +932,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->governor_enabled = 0;
smp_wmb();
del_timer_sync(&pcpu->cpu_timer);
+ del_timer_sync(&pcpu->cpu_slack_timer);
}
if (atomic_dec_return(&active_count) > 0)
@@ -940,6 +958,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
return 0;
}
+static void cpufreq_interactive_nop_timer(unsigned long data)
+{
+}
+
static int __init cpufreq_interactive_init(void)
{
unsigned int i;
@@ -954,12 +976,11 @@ static int __init cpufreq_interactive_init(void)
/* Initalize per-cpu timers */
for_each_possible_cpu(i) {
pcpu = &per_cpu(cpuinfo, i);
- if (governidle)
- init_timer(&pcpu->cpu_timer);
- else
- init_timer_deferrable(&pcpu->cpu_timer);
+ init_timer_deferrable(&pcpu->cpu_timer);
pcpu->cpu_timer.function = cpufreq_interactive_timer;
pcpu->cpu_timer.data = i;
+ init_timer(&pcpu->cpu_slack_timer);
+ pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer;
spin_lock_init(&pcpu->load_lock);
}
--
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