Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1256993 > unrolled thread
| Started by | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| First post | 2015-10-27 18:40 +0100 |
| Last post | 2015-10-29 02:50 +0100 |
| Articles | 20 on this page of 72 — 3 participants |
Back to article view | Back to linux.kernel
[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
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 63/70] cpufreq: interactive: remove compilation error from commit 49cc72365fb7ee87762a7ccc6a32ef68627216c5 |
| Message-ID | <qogxJ-87V-49@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Ruchi Kandoi <kandoiruchi@google.com>
Change-Id: I068b18281d03ac879ef64d8ff36ed43367293767
Signed-off-by: Ruchi Kandoi <kandoiruchi@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 3daca21..6c4b6a8 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -908,7 +908,7 @@ static ssize_t store_boost(struct cpufreq_interactive_tunables *tunables,
trace_cpufreq_interactive_boost("on");
cpufreq_interactive_boost();
} else {
- boostpulse_endtime = ktime_to_us(ktime_get());
+ tunables->boostpulse_endtime = ktime_to_us(ktime_get());
trace_cpufreq_interactive_unboost("off");
}
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 44/70] cpufreq: interactive: fix crash on error paths in get_tokenized_data |
| Message-ID | <qogxJ-87V-53@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Use separate variable for error code, free proper pointer.
Change-Id: Ia83cccb195997789ac6afbf5b8761f7b278196d6
Reported-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 7c734fa..3dc067e 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -647,29 +647,26 @@ static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
int i;
int ntokens = 1;
unsigned int *tokenized_data;
+ int err = -EINVAL;
cp = buf;
while ((cp = strpbrk(cp + 1, " :")))
ntokens++;
- if (!(ntokens & 0x1)) {
- tokenized_data = ERR_PTR(-EINVAL);
+ if (!(ntokens & 0x1))
goto err;
- }
tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
if (!tokenized_data) {
- tokenized_data = ERR_PTR(-ENOMEM);
+ err = -ENOMEM;
goto err;
}
cp = buf;
i = 0;
while (i < ntokens) {
- if (sscanf(cp, "%u", &tokenized_data[i++]) != 1) {
- tokenized_data = ERR_PTR(-EINVAL);
+ if (sscanf(cp, "%u", &tokenized_data[i++]) != 1)
goto err_kfree;
- }
cp = strpbrk(cp, " :");
if (!cp)
@@ -677,10 +674,8 @@ static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
cp++;
}
- if (i != ntokens) {
- tokenized_data = ERR_PTR(-EINVAL);
+ if (i != ntokens)
goto err_kfree;
- }
*num_tokens = ntokens;
return tokenized_data;
@@ -688,7 +683,7 @@ static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
err_kfree:
kfree(tokenized_data);
err:
- return tokenized_data;
+ return ERR_PTR(err);
}
static ssize_t show_target_loads(
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 50/70] cpufreq: interactive: fix race on cpufreq TRANSITION notifier |
| Message-ID | <qogxJ-87V-55@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Lianwei Wang <a22439@motorola.com>
The cpufreq TRANSTION notifier callback does not check the
governor_enabled state on affected CPUS, which will case
kernel panic in update_load because the policy object maybe
NULL or invalid when governor_enabled is false.
Change-Id: Ie0f1718124f61e2f9b5da57abc6981ada5b83908
Signed-off-by: Lianwei Wang <a22439@motorola.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 7303f50..691923d 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -634,9 +634,19 @@ static int cpufreq_interactive_notifier(
for_each_cpu(cpu, pcpu->policy->cpus) {
struct cpufreq_interactive_cpuinfo *pjcpu =
&per_cpu(cpuinfo, cpu);
+ if (cpu != freq->cpu) {
+ if (!down_read_trylock(&pjcpu->enable_sem))
+ continue;
+ if (!pjcpu->governor_enabled) {
+ up_read(&pjcpu->enable_sem);
+ continue;
+ }
+ }
spin_lock_irqsave(&pjcpu->load_lock, flags);
update_load(cpu);
spin_unlock_irqrestore(&pjcpu->load_lock, flags);
+ if (cpu != freq->cpu)
+ up_read(&pjcpu->enable_sem);
}
up_read(&pcpu->enable_sem);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 49/70] cpufreq: interactive: avoid underflow on active time calculation |
| Message-ID | <qogxJ-87V-59@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Minsung Kim <ms925.kim@samsung.com> Check for idle time delta less than elapsed time delta, avoid underflow computing active time. Change-Id: I3e4c6ef1ad794eec49ed379c0c50fa727fd6ad28 Signed-off-by: Minsung Kim <ms925.kim@samsung.com> Signed-off-by: Bálint Czobor <czoborbalint@gmail.com> --- drivers/cpufreq/cpufreq_interactive.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index b4d12b2..7303f50 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -325,7 +325,12 @@ static u64 update_load(int cpu) now_idle = get_cpu_idle_time(cpu, &now); delta_idle = (unsigned int)(now_idle - pcpu->time_in_idle); delta_time = (unsigned int)(now - pcpu->time_in_idle_timestamp); - active_time = delta_time - delta_idle; + + if (delta_time <= delta_idle) + active_time = 0; + else + active_time = delta_time - delta_idle; + pcpu->cputime_speedadj += active_time * pcpu->policy->cur; pcpu->time_in_idle = now_idle; -- 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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 45/70] cpufreq: interactive: base above_hispeed_delay on target freq, not current |
| Message-ID | <qogxJ-87V-63@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Time to wait should be based on the intended target speed, not the
actual speed (which may be held high by another CPU).
Change-Id: Ifc5bb55d06adddb9a02af90af05398a78f282272
Reported-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 3dc067e..9dd4d38 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -377,7 +377,7 @@ static void cpufreq_interactive_timer(unsigned long data)
if (pcpu->target_freq >= hispeed_freq &&
new_freq > pcpu->target_freq &&
now - pcpu->hispeed_validate_time <
- freq_to_above_hispeed_delay(pcpu->policy->cur)) {
+ freq_to_above_hispeed_delay(pcpu->target_freq)) {
trace_cpufreq_interactive_notyet(
data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 18:50 +0100 |
| Subject | [PATCH 46/70] cpufreq: interactive: fix uninitialized spinlock |
| Message-ID | <qogxJ-87V-71@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Minsung Kim <ms925.kim@samsung.com> Add missing spinlock init Backtrace: [<c0011ce4>] (dump_backtrace+0x0/0x10c) from [<c0662a68>] (dump_stack+0x18/0x1c) r6:00000032 r5:c0bd09ec r4:e6848000 r3:00000000 [<c0662a50>] (dump_stack+0x0/0x1c) from [<c06670b0>] (spin_dump+0x80/0x94) [<c0667030>] (spin_dump+0x0/0x94) from [<c06670f0>] (spin_bug+0x2c/0x30) r5:c08f91fc r4:c0bd09ec [<c06670c4>] (spin_bug+0x0/0x30) from [<c0245f74>] (do_raw_spin_unlock+0x88/0xcc) r5:e547bac0 r4:c0bd09ec [<c0245eec>] (do_raw_spin_unlock+0x0/0xcc) from [<c066c9cc>] (_raw_spin_unlock_irqrestore+0x14/0x40) r5:e547bac0 r4:60000013 [<c066c9b8>] (_raw_spin_unlock_irqrestore+0x0/0x40) from [<c044b884>] (store_above_hispeed_delay+0x6c/0x80) r4:c0b4cf78 r3:00000007 [<c044b818>] (store_above_hispeed_delay+0x0/0x80) from [<c0235d24>] (kobj_attr_store+0x1c/0x28) r7:e68ff000 r6:00000032 r5:e58137c0 r4:e61cde80 [<c0235d08>] (kobj_attr_store+0x0/0x28) from [<c0156b78>] (sysfs_write_file+0x104/0x184) [<c0156a74>] (sysfs_write_file+0x0/0x184) from [<c0100680>] (vfs_write+0xb0/0x140) [<c01005d0>] (vfs_write+0x0/0x140) from [<c0100900>] (sys_write+0x44/0x70) r8:00000000 r7:00000004 r6:00000032 r5:bee43c90 r4:e5600300 [<c01008bc>] (sys_write+0x0/0x70) from [<c000e400>] (ret_fast_syscall+0x0/0x30) r9:e6842000 r8:c000e584 r6:00000032 r5:bee43c90 r4:00000009 Change-Id: I80a1e0b3fecb24adba501ff44f568479deeff7fa Signed-off-by: Minsung Kim <ms925.kim@samsung.com> Signed-off-by: Bálint Czobor <czoborbalint@gmail.com> --- drivers/cpufreq/cpufreq_interactive.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 9dd4d38..baf8740 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1148,6 +1148,7 @@ static int __init cpufreq_interactive_init(void) spin_lock_init(&target_loads_lock); spin_lock_init(&speedchange_cpumask_lock); + spin_lock_init(&above_hispeed_delay_lock); mutex_init(&gov_lock); speedchange_task = kthread_create(cpufreq_interactive_speedchange_task, NULL, -- 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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 34/70] cpufreq: interactive: fix boosting logic |
| Message-ID | <qogHn-8bo-1@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
35a84de cpufreq: interactive: apply above_hispeed_delay to each step above hispeed
caused the speed choice logic to osciallate between boosting and not boosting.
Add back code to ensure speed does not drop below boost frequency while
boosting.
Change-Id: Id420068480fcc7f5c4989ff523e2a8d22e2f4db2
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 690be16..f8e9ee9 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -298,11 +298,18 @@ static void cpufreq_interactive_timer(unsigned long data)
cpu_load = loadadjfreq / pcpu->target_freq;
boosted = boost_val || now < boostpulse_endtime;
- if ((cpu_load >= go_hispeed_load || boosted) &&
- pcpu->target_freq < hispeed_freq)
- new_freq = hispeed_freq;
- else
+ if (cpu_load >= go_hispeed_load || boosted) {
+ if (pcpu->target_freq < hispeed_freq) {
+ new_freq = hispeed_freq;
+ } else {
+ new_freq = choose_freq(pcpu, loadadjfreq);
+
+ if (new_freq < hispeed_freq)
+ new_freq = hispeed_freq;
+ }
+ } else {
new_freq = choose_freq(pcpu, loadadjfreq);
+ }
if (pcpu->target_freq >= hispeed_freq &&
new_freq > pcpu->target_freq &&
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 38/70] cpufreq: interactive: init default values at compile time |
| Message-ID | <qogHn-8bo-3@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Change-Id: Ia4966e949a6c24c34fdbd4a6e522cd7c37e4108e
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index fdc2a47..c8358a3 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -67,7 +67,7 @@ static unsigned int hispeed_freq;
/* Go to hi speed when CPU load at or above this value. */
#define DEFAULT_GO_HISPEED_LOAD 99
-static unsigned long go_hispeed_load;
+static unsigned long go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
/* Target load. Lower values result in higher CPU speeds. */
#define DEFAULT_TARGET_LOAD 90
@@ -80,20 +80,20 @@ static int ntarget_loads = ARRAY_SIZE(default_target_loads);
* The minimum amount of time to spend at a frequency before we can ramp down.
*/
#define DEFAULT_MIN_SAMPLE_TIME (80 * USEC_PER_MSEC)
-static unsigned long min_sample_time;
+static unsigned long min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
/*
* The sample rate of the timer used to increase frequency
*/
#define DEFAULT_TIMER_RATE (20 * USEC_PER_MSEC)
-static unsigned long timer_rate;
+static unsigned long timer_rate = DEFAULT_TIMER_RATE;
/*
* Wait this long before raising speed above hispeed, by default a single
* timer interval.
*/
#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE
-static unsigned long above_hispeed_delay_val;
+static unsigned long above_hispeed_delay_val = DEFAULT_ABOVE_HISPEED_DELAY;
/* Non-zero means indefinite speed boost active */
static int boost_val;
@@ -992,11 +992,6 @@ static int __init cpufreq_interactive_init(void)
struct cpufreq_interactive_cpuinfo *pcpu;
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
- go_hispeed_load = DEFAULT_GO_HISPEED_LOAD;
- min_sample_time = DEFAULT_MIN_SAMPLE_TIME;
- above_hispeed_delay_val = DEFAULT_ABOVE_HISPEED_DELAY;
- timer_rate = DEFAULT_TIMER_RATE;
-
/* Initalize per-cpu timers */
for_each_possible_cpu(i) {
pcpu = &per_cpu(cpuinfo, i);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 16/70] cpufreq: interactive: restart above_hispeed_delay at each hispeed load |
| Message-ID | <qogHn-8bo-5@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Change-Id: I2e5b91d45e8806b0ab94ca2301ed671c9af9ab13
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 7cb2e64..a4ed750 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -52,6 +52,7 @@ struct cpufreq_interactive_cpuinfo {
unsigned int target_freq;
unsigned int floor_freq;
u64 floor_validate_time;
+ u64 hispeed_validate_time;
int governor_enabled;
};
@@ -206,7 +207,7 @@ static void cpufreq_interactive_timer(unsigned long data)
if (pcpu->target_freq == hispeed_freq &&
new_freq > hispeed_freq &&
- pcpu->timer_run_time - pcpu->target_set_time
+ pcpu->timer_run_time - pcpu->hispeed_validate_time
< above_hispeed_delay_val) {
trace_cpufreq_interactive_notyet(data, cpu_load,
pcpu->target_freq,
@@ -218,6 +219,9 @@ static void cpufreq_interactive_timer(unsigned long data)
new_freq = pcpu->policy->max * cpu_load / 100;
}
+ if (new_freq <= hispeed_freq)
+ pcpu->hispeed_validate_time = pcpu->timer_run_time;
+
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
new_freq, CPUFREQ_RELATION_H,
&index)) {
@@ -505,6 +509,7 @@ static void cpufreq_interactive_boost(void)
cpumask_set_cpu(i, &up_cpumask);
pcpu->target_set_time_in_idle =
get_cpu_idle_time_us(i, &pcpu->target_set_time);
+ pcpu->hispeed_validate_time = pcpu->target_set_time;
anyboost = 1;
}
@@ -838,6 +843,8 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->floor_freq = pcpu->target_freq;
pcpu->floor_validate_time =
pcpu->target_set_time;
+ pcpu->hispeed_validate_time =
+ pcpu->target_set_time;
pcpu->governor_enabled = 1;
smp_wmb();
}
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 28/70] cpufreq: interactive: apply above_hispeed_delay to each step above hispeed |
| Message-ID | <qogHn-8bo-7@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Apply above_hispeed_delay whenever increasing speed to a new speed above
hispeed (not just the first step above hispeed).
Change-Id: Ibb7add7db47f2a4306a9458c4e1ebabb60698636
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 36 ++++++++++++---------------------
1 file changed, 13 insertions(+), 23 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index c4293c5..17c42cc 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -176,32 +176,22 @@ static void cpufreq_interactive_timer(unsigned long data)
if (load_since_change > cpu_load)
cpu_load = load_since_change;
- if (cpu_load >= go_hispeed_load || boost_val) {
- if (pcpu->target_freq < hispeed_freq &&
- hispeed_freq < pcpu->policy->max) {
- new_freq = hispeed_freq;
- } else {
- new_freq = pcpu->policy->cur * cpu_load / target_load;
-
- if (new_freq < hispeed_freq)
- new_freq = hispeed_freq;
-
- if (pcpu->target_freq == hispeed_freq &&
- new_freq > hispeed_freq &&
- now - pcpu->hispeed_validate_time
- < above_hispeed_delay_val) {
- trace_cpufreq_interactive_notyet(
- data, cpu_load, pcpu->target_freq,
- pcpu->policy->cur, new_freq);
- goto rearm;
- }
- }
- } else {
+ if ((cpu_load >= go_hispeed_load || boost_val) &&
+ pcpu->target_freq < hispeed_freq)
+ new_freq = hispeed_freq;
+ else
new_freq = pcpu->policy->cur * cpu_load / target_load;
+
+ if (pcpu->target_freq >= hispeed_freq &&
+ new_freq > pcpu->target_freq &&
+ now - pcpu->hispeed_validate_time < above_hispeed_delay_val) {
+ trace_cpufreq_interactive_notyet(
+ data, cpu_load, pcpu->target_freq,
+ pcpu->policy->cur, new_freq);
+ goto rearm;
}
- if (new_freq <= hispeed_freq)
- pcpu->hispeed_validate_time = now;
+ pcpu->hispeed_validate_time = now;
if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
new_freq, CPUFREQ_RELATION_L,
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 23/70] cpufreq: interactive: pin timers to associated CPU |
| Message-ID | <qogHo-8bo-11@gated-at.bofh.it> |
| In reply to | #1256993 |
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 18/70] cpufreq: interactive: keep freezer happy when not current governor |
| Message-ID | <qogHo-8bo-17@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Sam Leffler <sleffler@chromium.org> Fix a problem where the hung task mechanism was deeming the interactive clock boost thread as hung. This was because the thread is created at module init but never run/woken up until needed. If the governor is not being used this can be forever. To workaround this explicitly wake up the thread once all the necessary data structures are initialized. The latter required some minor code shuffle. Signed-off-by: Sam Leffler <sleffler@chromium.org> Change-Id: Ie2c058dd75dcb6460ea10e7ac997e46baf66b1fe Signed-off-by: Bálint Czobor <czoborbalint@gmail.com> --- drivers/cpufreq/cpufreq_interactive.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 2038991..184140a 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -953,6 +953,10 @@ static int __init cpufreq_interactive_init(void) pcpu->cpu_timer.data = i; } + spin_lock_init(&up_cpumask_lock); + spin_lock_init(&down_cpumask_lock); + mutex_init(&set_speed_lock); + up_task = kthread_create(cpufreq_interactive_up_task, NULL, "kinteractiveup"); if (IS_ERR(up_task)) @@ -968,14 +972,12 @@ static int __init cpufreq_interactive_init(void) if (!down_wq) goto err_freeuptask; - INIT_WORK(&freq_scale_down_work, - cpufreq_interactive_freq_down); + INIT_WORK(&freq_scale_down_work, cpufreq_interactive_freq_down); + INIT_WORK(&inputopen.inputopen_work, cpufreq_interactive_input_open); - spin_lock_init(&up_cpumask_lock); - spin_lock_init(&down_cpumask_lock); - mutex_init(&set_speed_lock); + /* NB: wake up so the thread does not look hung to the freezer */ + wake_up_process(up_task); - INIT_WORK(&inputopen.inputopen_work, cpufreq_interactive_input_open); return cpufreq_register_governor(&cpufreq_gov_interactive); err_freeuptask: -- 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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 21/70] cpufreq: interactive: always limit initial speed bump to hispeed |
| Message-ID | <qogHo-8bo-19@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
First bump speed up to hispeed_freq whenever the current speed is below
hispeed_freq, instead of only when the current speed is the minimum speed.
The previous code made it too difficult to use hispeed_freq as a common
intermediate speed on systems that frequently run at speeds between
minimum and hispeed_freq.
Change-Id: I04ec30bafabf5741e267ff289209b8c2d846824b
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 4b60b6e..f85fbbd 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -178,7 +178,8 @@ static void cpufreq_interactive_timer(unsigned long data)
cpu_load = load_since_change;
if (cpu_load >= go_hispeed_load || boost_val) {
- if (pcpu->target_freq <= pcpu->policy->min) {
+ if (pcpu->target_freq < hispeed_freq &&
+ hispeed_freq < pcpu->policy->max) {
new_freq = hispeed_freq;
} else {
new_freq = pcpu->policy->max * cpu_load / 100;
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 36/70] cpufreq: interactive: fix race on timer restart on governor start |
| Message-ID | <qogHo-8bo-21@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Starting the governor, or restarting on a hotplugged-in CPU, can race
with the timer start in idle, triggering a BUG on timer already pending.
Start the timer before setting the enable flag, and use enable_sem to
protect the sequence (and ensure correct order of the update to the
enable flag). Delete any existing timer for safety.
Change-Id: Ife77cf9fe099e8fd8543224cbf148c6722c2ffb0
Reported-by: Francisco Franco <francisco.franco@cloudcar.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 74f5609..d22d162 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -919,17 +919,17 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
ktime_to_us(ktime_get());
pcpu->hispeed_validate_time =
pcpu->floor_validate_time;
- pcpu->governor_enabled = 1;
- smp_wmb();
+ down_write(&pcpu->enable_sem);
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);
}
+ pcpu->governor_enabled = 1;
+ up_write(&pcpu->enable_sem);
}
/*
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 19/70] cpufreq: interactive: handle speed up and down in the realtime task |
| Message-ID | <qogHp-8bo-37@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Not useful to have a separate, non-realtime workqueue for speed down
events, avoid priority inversion for speed up events.
Change-Id: Iddcd05545245c847aa1bbe0b8790092914c813d2
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 148 +++++++++-------------------
include/trace/events/cpufreq_interactive.h | 8 +-
2 files changed, 45 insertions(+), 111 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 184140a..e9c8516 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -58,15 +58,10 @@ struct cpufreq_interactive_cpuinfo {
static DEFINE_PER_CPU(struct cpufreq_interactive_cpuinfo, cpuinfo);
-/* Workqueues handle frequency scaling */
-static struct task_struct *up_task;
-static struct workqueue_struct *down_wq;
-static struct work_struct freq_scale_down_work;
-static cpumask_t up_cpumask;
-static spinlock_t up_cpumask_lock;
-static cpumask_t down_cpumask;
-static spinlock_t down_cpumask_lock;
-static struct mutex set_speed_lock;
+/* realtime thread handles frequency scaling */
+static struct task_struct *speedchange_task;
+static cpumask_t speedchange_cpumask;
+static spinlock_t speedchange_cpumask_lock;
/* Hi speed to bump to from lo speed when load burst (default max) */
static u64 hispeed_freq;
@@ -106,6 +101,7 @@ struct cpufreq_interactive_inputopen {
};
static struct cpufreq_interactive_inputopen inputopen;
+static struct workqueue_struct *inputopen_wq;
/*
* Non-zero means longer-term speed boost active.
@@ -259,19 +255,11 @@ static void cpufreq_interactive_timer(unsigned long data)
pcpu->target_set_time_in_idle = now_idle;
pcpu->target_set_time = pcpu->timer_run_time;
- if (new_freq < pcpu->target_freq) {
- pcpu->target_freq = new_freq;
- spin_lock_irqsave(&down_cpumask_lock, flags);
- cpumask_set_cpu(data, &down_cpumask);
- spin_unlock_irqrestore(&down_cpumask_lock, flags);
- queue_work(down_wq, &freq_scale_down_work);
- } else {
- pcpu->target_freq = new_freq;
- spin_lock_irqsave(&up_cpumask_lock, flags);
- cpumask_set_cpu(data, &up_cpumask);
- spin_unlock_irqrestore(&up_cpumask_lock, flags);
- wake_up_process(up_task);
- }
+ pcpu->target_freq = new_freq;
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
+ cpumask_set_cpu(data, &speedchange_cpumask);
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
+ wake_up_process(speedchange_task);
rearm_if_notmax:
/*
@@ -394,7 +382,7 @@ static void cpufreq_interactive_idle_end(void)
}
-static int cpufreq_interactive_up_task(void *data)
+static int cpufreq_interactive_speedchange_task(void *data)
{
unsigned int cpu;
cpumask_t tmp_mask;
@@ -403,22 +391,23 @@ static int cpufreq_interactive_up_task(void *data)
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
- spin_lock_irqsave(&up_cpumask_lock, flags);
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
- if (cpumask_empty(&up_cpumask)) {
- spin_unlock_irqrestore(&up_cpumask_lock, flags);
+ if (cpumask_empty(&speedchange_cpumask)) {
+ spin_unlock_irqrestore(&speedchange_cpumask_lock,
+ flags);
schedule();
if (kthread_should_stop())
break;
- spin_lock_irqsave(&up_cpumask_lock, flags);
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
}
set_current_state(TASK_RUNNING);
- tmp_mask = up_cpumask;
- cpumask_clear(&up_cpumask);
- spin_unlock_irqrestore(&up_cpumask_lock, flags);
+ tmp_mask = speedchange_cpumask;
+ cpumask_clear(&speedchange_cpumask);
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
for_each_cpu(cpu, &tmp_mask) {
unsigned int j;
@@ -430,8 +419,6 @@ static int cpufreq_interactive_up_task(void *data)
if (!pcpu->governor_enabled)
continue;
- mutex_lock(&set_speed_lock);
-
for_each_cpu(j, pcpu->policy->cpus) {
struct cpufreq_interactive_cpuinfo *pjcpu =
&per_cpu(cpuinfo, j);
@@ -444,8 +431,8 @@ static int cpufreq_interactive_up_task(void *data)
__cpufreq_driver_target(pcpu->policy,
max_freq,
CPUFREQ_RELATION_H);
- mutex_unlock(&set_speed_lock);
- trace_cpufreq_interactive_up(cpu, pcpu->target_freq,
+ trace_cpufreq_interactive_setspeed(cpu,
+ pcpu->target_freq,
pcpu->policy->cur);
}
}
@@ -453,48 +440,6 @@ static int cpufreq_interactive_up_task(void *data)
return 0;
}
-static void cpufreq_interactive_freq_down(struct work_struct *work)
-{
- unsigned int cpu;
- cpumask_t tmp_mask;
- unsigned long flags;
- struct cpufreq_interactive_cpuinfo *pcpu;
-
- spin_lock_irqsave(&down_cpumask_lock, flags);
- tmp_mask = down_cpumask;
- cpumask_clear(&down_cpumask);
- spin_unlock_irqrestore(&down_cpumask_lock, flags);
-
- for_each_cpu(cpu, &tmp_mask) {
- unsigned int j;
- unsigned int max_freq = 0;
-
- pcpu = &per_cpu(cpuinfo, cpu);
- smp_rmb();
-
- if (!pcpu->governor_enabled)
- continue;
-
- mutex_lock(&set_speed_lock);
-
- for_each_cpu(j, pcpu->policy->cpus) {
- struct cpufreq_interactive_cpuinfo *pjcpu =
- &per_cpu(cpuinfo, j);
-
- if (pjcpu->target_freq > max_freq)
- max_freq = pjcpu->target_freq;
- }
-
- if (max_freq != pcpu->policy->cur)
- __cpufreq_driver_target(pcpu->policy, max_freq,
- CPUFREQ_RELATION_H);
-
- mutex_unlock(&set_speed_lock);
- trace_cpufreq_interactive_down(cpu, pcpu->target_freq,
- pcpu->policy->cur);
- }
-}
-
static void cpufreq_interactive_boost(void)
{
int i;
@@ -502,14 +447,14 @@ static void cpufreq_interactive_boost(void)
unsigned long flags;
struct cpufreq_interactive_cpuinfo *pcpu;
- spin_lock_irqsave(&up_cpumask_lock, flags);
+ spin_lock_irqsave(&speedchange_cpumask_lock, flags);
for_each_online_cpu(i) {
pcpu = &per_cpu(cpuinfo, i);
if (pcpu->target_freq < hispeed_freq) {
pcpu->target_freq = hispeed_freq;
- cpumask_set_cpu(i, &up_cpumask);
+ cpumask_set_cpu(i, &speedchange_cpumask);
pcpu->target_set_time_in_idle =
get_cpu_idle_time_us(i, &pcpu->target_set_time);
pcpu->hispeed_validate_time = pcpu->target_set_time;
@@ -525,10 +470,10 @@ static void cpufreq_interactive_boost(void)
pcpu->floor_validate_time = ktime_to_us(ktime_get());
}
- spin_unlock_irqrestore(&up_cpumask_lock, flags);
+ spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
if (anyboost)
- wake_up_process(up_task);
+ wake_up_process(speedchange_task);
}
/*
@@ -580,7 +525,7 @@ static int cpufreq_interactive_input_connect(struct input_handler *handler,
goto err;
inputopen.handle = handle;
- queue_work(down_wq, &inputopen.inputopen_work);
+ queue_work(inputopen_wq, &inputopen.inputopen_work);
return 0;
err:
kfree(handle);
@@ -911,7 +856,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->idle_exit_time = 0;
}
- flush_work(&freq_scale_down_work);
+ flush_work(&inputopen.inputopen_work);
if (atomic_dec_return(&active_count) > 0)
return 0;
@@ -953,35 +898,30 @@ static int __init cpufreq_interactive_init(void)
pcpu->cpu_timer.data = i;
}
- spin_lock_init(&up_cpumask_lock);
- spin_lock_init(&down_cpumask_lock);
- mutex_init(&set_speed_lock);
-
- up_task = kthread_create(cpufreq_interactive_up_task, NULL,
- "kinteractiveup");
- if (IS_ERR(up_task))
- return PTR_ERR(up_task);
+ spin_lock_init(&speedchange_cpumask_lock);
+ speedchange_task =
+ kthread_create(cpufreq_interactive_speedchange_task, NULL,
+ "cfinteractive");
+ if (IS_ERR(speedchange_task))
+ return PTR_ERR(speedchange_task);
- sched_setscheduler_nocheck(up_task, SCHED_FIFO, ¶m);
- get_task_struct(up_task);
+ sched_setscheduler_nocheck(speedchange_task, SCHED_FIFO, ¶m);
+ get_task_struct(speedchange_task);
- /* No rescuer thread, bind to CPU queuing the work for possibly
- warm cache (probably doesn't matter much). */
- down_wq = alloc_workqueue("knteractive_down", 0, 1);
+ inputopen_wq = create_workqueue("cfinteractive");
- if (!down_wq)
- goto err_freeuptask;
+ if (!inputopen_wq)
+ goto err_freetask;
- INIT_WORK(&freq_scale_down_work, cpufreq_interactive_freq_down);
INIT_WORK(&inputopen.inputopen_work, cpufreq_interactive_input_open);
/* NB: wake up so the thread does not look hung to the freezer */
- wake_up_process(up_task);
+ wake_up_process(speedchange_task);
return cpufreq_register_governor(&cpufreq_gov_interactive);
-err_freeuptask:
- put_task_struct(up_task);
+err_freetask:
+ put_task_struct(speedchange_task);
return -ENOMEM;
}
@@ -994,9 +934,9 @@ module_init(cpufreq_interactive_init);
static void __exit cpufreq_interactive_exit(void)
{
cpufreq_unregister_governor(&cpufreq_gov_interactive);
- kthread_stop(up_task);
- put_task_struct(up_task);
- destroy_workqueue(down_wq);
+ kthread_stop(speedchange_task);
+ put_task_struct(speedchange_task);
+ destroy_workqueue(inputopen_wq);
}
module_exit(cpufreq_interactive_exit);
diff --git a/include/trace/events/cpufreq_interactive.h b/include/trace/events/cpufreq_interactive.h
index 0791f27..ba0634e 100644
--- a/include/trace/events/cpufreq_interactive.h
+++ b/include/trace/events/cpufreq_interactive.h
@@ -28,13 +28,7 @@ DECLARE_EVENT_CLASS(set,
__entry->actualfreq)
);
-DEFINE_EVENT(set, cpufreq_interactive_up,
- TP_PROTO(u32 cpu_id, unsigned long targfreq,
- unsigned long actualfreq),
- TP_ARGS(cpu_id, targfreq, actualfreq)
-);
-
-DEFINE_EVENT(set, cpufreq_interactive_down,
+DEFINE_EVENT(set, cpufreq_interactive_setspeed,
TP_PROTO(u32 cpu_id, unsigned long targfreq,
unsigned long actualfreq),
TP_ARGS(cpu_id, targfreq, actualfreq)
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 42/70] cpufreq: interactive: allow arbitrary speed / delay mappings |
| Message-ID | <qogHp-8bo-41@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Minsung Kim <ms925.kim@samsung.com>
Accept a string of delays and speeds at which to apply the delay before
raising each step above hispeed. For example, "80000 1300000:200000
1500000:40000" means that the delay at or above 1GHz, until 1.3GHz is 80 msecs,
the delay until 1.5GHz is 200 msecs and the delay at or above 1.5GHz is 40
msecs when hispeed_freq is 1GHz.
[toddpoynor@google.com: add documentation]
Change-Id: Ifeebede8b1acbdd0a53e5c6916bccbf764dc854f
Signed-off-by: Minsung Kim <ms925.kim@samsung.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
Documentation/cpu-freq/governors.txt | 12 ++-
drivers/cpufreq/cpufreq_interactive.c | 185 ++++++++++++++++++++++-----------
2 files changed, 134 insertions(+), 63 deletions(-)
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 4d8ae34..ac8a37e 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -260,7 +260,17 @@ Default is 99%.
above_hispeed_delay: When speed is at or above hispeed_freq, wait for
this long before raising speed in response to continued high load.
-Default is 20000 uS.
+The format is a single delay value, optionally followed by pairs of
+CPU speeds and the delay to use at or above those speeds. Colons can
+be used between the speeds and associated delays for readability. For
+example:
+
+ 80000 1300000:200000 1500000:40000
+
+uses delay 80000 uS until CPU speed 1.3 GHz, at which speed delay
+200000 uS is used until speed 1.5 GHz, at which speed (and above)
+delay 40000 uS is used. If speeds are specified these must appear in
+ascending order. Default is 20000 uS.
timer_rate: Sample rate for reevaluating CPU load when the CPU is not
idle. A deferrable timer is used, such that the CPU will not be woken
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 3447e58..620b46c 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -94,7 +94,11 @@ static unsigned long timer_rate = DEFAULT_TIMER_RATE;
* timer interval.
*/
#define DEFAULT_ABOVE_HISPEED_DELAY DEFAULT_TIMER_RATE
-static unsigned long above_hispeed_delay_val = DEFAULT_ABOVE_HISPEED_DELAY;
+static unsigned int default_above_hispeed_delay[] = {
+ DEFAULT_ABOVE_HISPEED_DELAY };
+static spinlock_t above_hispeed_delay_lock;
+static unsigned int *above_hispeed_delay = default_above_hispeed_delay;
+static int nabove_hispeed_delay = ARRAY_SIZE(default_above_hispeed_delay);
/* Non-zero means indefinite speed boost active */
static int boost_val;
@@ -144,6 +148,23 @@ static void cpufreq_interactive_timer_resched(
spin_unlock_irqrestore(&pcpu->load_lock, flags);
}
+static unsigned int freq_to_above_hispeed_delay(unsigned int freq)
+{
+ int i;
+ unsigned int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&above_hispeed_delay_lock, flags);
+
+ for (i = 0; i < nabove_hispeed_delay - 1 &&
+ freq >= above_hispeed_delay[i+1]; i += 2)
+ ;
+
+ ret = above_hispeed_delay[i];
+ spin_unlock_irqrestore(&above_hispeed_delay_lock, flags);
+ return ret;
+}
+
static unsigned int freq_to_targetload(unsigned int freq)
{
int i;
@@ -316,7 +337,8 @@ static void cpufreq_interactive_timer(unsigned long data)
if (pcpu->target_freq >= hispeed_freq &&
new_freq > pcpu->target_freq &&
- now - pcpu->hispeed_validate_time < above_hispeed_delay_val) {
+ now - pcpu->hispeed_validate_time <
+ freq_to_above_hispeed_delay(pcpu->policy->cur)) {
trace_cpufreq_interactive_notyet(
data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
@@ -580,6 +602,56 @@ static struct notifier_block cpufreq_notifier_block = {
.notifier_call = cpufreq_interactive_notifier,
};
+static unsigned int *get_tokenized_data(const char *buf, int *num_tokens)
+{
+ const char *cp;
+ int i;
+ int ntokens = 1;
+ unsigned int *tokenized_data;
+
+ cp = buf;
+ while ((cp = strpbrk(cp + 1, " :")))
+ ntokens++;
+
+ if (!(ntokens & 0x1)) {
+ tokenized_data = ERR_PTR(-EINVAL);
+ goto err;
+ }
+
+ tokenized_data = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
+ if (!tokenized_data) {
+ tokenized_data = ERR_PTR(-ENOMEM);
+ goto err;
+ }
+
+ cp = buf;
+ i = 0;
+ while (i < ntokens) {
+ if (sscanf(cp, "%u", &tokenized_data[i++]) != 1) {
+ tokenized_data = ERR_PTR(-EINVAL);
+ goto err_kfree;
+ }
+
+ cp = strpbrk(cp, " :");
+ if (!cp)
+ break;
+ cp++;
+ }
+
+ if (i != ntokens) {
+ tokenized_data = ERR_PTR(-EINVAL);
+ goto err_kfree;
+ }
+
+ *num_tokens = ntokens;
+ return tokenized_data;
+
+err_kfree:
+ kfree(tokenized_data);
+err:
+ return tokenized_data;
+}
+
static ssize_t show_target_loads(
struct kobject *kobj, struct attribute *attr, char *buf)
{
@@ -602,40 +674,13 @@ static ssize_t store_target_loads(
struct kobject *kobj, struct attribute *attr, const char *buf,
size_t count)
{
- int ret;
- const char *cp;
+ int ntokens;
unsigned int *new_target_loads = NULL;
- int ntokens = 1;
- int i;
unsigned long flags;
- cp = buf;
- while ((cp = strpbrk(cp + 1, " :")))
- ntokens++;
-
- if (!(ntokens & 0x1))
- goto err_inval;
-
- new_target_loads = kmalloc(ntokens * sizeof(unsigned int), GFP_KERNEL);
- if (!new_target_loads) {
- ret = -ENOMEM;
- goto err;
- }
-
- cp = buf;
- i = 0;
- while (i < ntokens) {
- if (sscanf(cp, "%u", &new_target_loads[i++]) != 1)
- goto err_inval;
-
- cp = strpbrk(cp, " :");
- if (!cp)
- break;
- cp++;
- }
-
- if (i != ntokens)
- goto err_inval;
+ new_target_loads = get_tokenized_data(buf, &ntokens);
+ if (IS_ERR(new_target_loads))
+ return PTR_RET(new_target_loads);
spin_lock_irqsave(&target_loads_lock, flags);
if (target_loads != default_target_loads)
@@ -644,18 +689,56 @@ static ssize_t store_target_loads(
ntarget_loads = ntokens;
spin_unlock_irqrestore(&target_loads_lock, flags);
return count;
-
-err_inval:
- ret = -EINVAL;
-err:
- kfree(new_target_loads);
- return ret;
}
static struct global_attr target_loads_attr =
__ATTR(target_loads, S_IRUGO | S_IWUSR,
show_target_loads, store_target_loads);
+static ssize_t show_above_hispeed_delay(
+ struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ int i;
+ ssize_t ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&above_hispeed_delay_lock, flags);
+
+ for (i = 0; i < nabove_hispeed_delay; i++)
+ ret += sprintf(buf + ret, "%u%s", above_hispeed_delay[i],
+ i & 0x1 ? ":" : " ");
+
+ ret += sprintf(buf + ret, "\n");
+ spin_unlock_irqrestore(&above_hispeed_delay_lock, flags);
+ return ret;
+}
+
+static ssize_t store_above_hispeed_delay(
+ struct kobject *kobj, struct attribute *attr, const char *buf,
+ size_t count)
+{
+ int ntokens;
+ unsigned int *new_above_hispeed_delay = NULL;
+ unsigned long flags;
+
+ new_above_hispeed_delay = get_tokenized_data(buf, &ntokens);
+ if (IS_ERR(new_above_hispeed_delay))
+ return PTR_RET(new_above_hispeed_delay);
+
+ spin_lock_irqsave(&above_hispeed_delay_lock, flags);
+ if (above_hispeed_delay != default_above_hispeed_delay)
+ kfree(above_hispeed_delay);
+ above_hispeed_delay = new_above_hispeed_delay;
+ nabove_hispeed_delay = ntokens;
+ spin_unlock_irqrestore(&above_hispeed_delay_lock, flags);
+ return count;
+
+}
+
+static struct global_attr above_hispeed_delay_attr =
+ __ATTR(above_hispeed_delay, S_IRUGO | S_IWUSR,
+ show_above_hispeed_delay, store_above_hispeed_delay);
+
static ssize_t show_hispeed_freq(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -724,28 +807,6 @@ static ssize_t store_min_sample_time(struct kobject *kobj,
static struct global_attr min_sample_time_attr = __ATTR(min_sample_time, 0644,
show_min_sample_time, store_min_sample_time);
-static ssize_t show_above_hispeed_delay(struct kobject *kobj,
- struct attribute *attr, char *buf)
-{
- return sprintf(buf, "%lu\n", above_hispeed_delay_val);
-}
-
-static ssize_t store_above_hispeed_delay(struct kobject *kobj,
- struct attribute *attr,
- const char *buf, size_t count)
-{
- int ret;
- unsigned long val;
-
- ret = strict_strtoul(buf, 0, &val);
- if (ret < 0)
- return ret;
- above_hispeed_delay_val = val;
- return count;
-}
-
-define_one_global_rw(above_hispeed_delay);
-
static ssize_t show_timer_rate(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -865,9 +926,9 @@ define_one_global_rw(boostpulse_duration);
static struct attribute *interactive_attributes[] = {
&target_loads_attr.attr,
+ &above_hispeed_delay_attr.attr,
&hispeed_freq_attr.attr,
&go_hispeed_load_attr.attr,
- &above_hispeed_delay.attr,
&min_sample_time_attr.attr,
&timer_rate_attr.attr,
&timer_slack.attr,
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 26/70] cpufreq: interactive: trace actual speed in target speed decisions |
| Message-ID | <qogHp-8bo-47@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Tracing adds actual speed since this is expected to be key to the
choice of target speed.
Change-Id: Iec936102d0010c4e9dfa143c38a9fd0d551189c3
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 18 +++++++-------
include/trace/events/cpufreq_interactive.h | 36 ++++++++++++++++------------
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 8153769..2b4aad9 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -186,9 +186,9 @@ static void cpufreq_interactive_timer(unsigned long data)
new_freq > hispeed_freq &&
now - pcpu->hispeed_validate_time
< above_hispeed_delay_val) {
- trace_cpufreq_interactive_notyet(data, cpu_load,
- pcpu->target_freq,
- new_freq);
+ trace_cpufreq_interactive_notyet(
+ data, cpu_load, pcpu->target_freq,
+ pcpu->policy->cur, new_freq);
goto rearm;
}
}
@@ -215,8 +215,9 @@ static void cpufreq_interactive_timer(unsigned long data)
*/
if (new_freq < pcpu->floor_freq) {
if (now - pcpu->floor_validate_time < min_sample_time) {
- trace_cpufreq_interactive_notyet(data, cpu_load,
- pcpu->target_freq, new_freq);
+ trace_cpufreq_interactive_notyet(
+ data, cpu_load, pcpu->target_freq,
+ pcpu->policy->cur, new_freq);
goto rearm;
}
}
@@ -225,13 +226,14 @@ static void cpufreq_interactive_timer(unsigned long data)
pcpu->floor_validate_time = now;
if (pcpu->target_freq == new_freq) {
- trace_cpufreq_interactive_already(data, cpu_load,
- pcpu->target_freq, new_freq);
+ trace_cpufreq_interactive_already(
+ data, cpu_load, pcpu->target_freq,
+ pcpu->policy->cur, new_freq);
goto rearm_if_notmax;
}
trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
- new_freq);
+ pcpu->policy->cur, new_freq);
pcpu->target_set_time_in_idle = now_idle;
pcpu->target_set_time = now;
diff --git a/include/trace/events/cpufreq_interactive.h b/include/trace/events/cpufreq_interactive.h
index ba0634e..b2ce6b0 100644
--- a/include/trace/events/cpufreq_interactive.h
+++ b/include/trace/events/cpufreq_interactive.h
@@ -36,44 +36,50 @@ DEFINE_EVENT(set, cpufreq_interactive_setspeed,
DECLARE_EVENT_CLASS(loadeval,
TP_PROTO(unsigned long cpu_id, unsigned long load,
- unsigned long curfreq, unsigned long targfreq),
- TP_ARGS(cpu_id, load, curfreq, targfreq),
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg),
TP_STRUCT__entry(
__field(unsigned long, cpu_id )
__field(unsigned long, load )
- __field(unsigned long, curfreq )
- __field(unsigned long, targfreq )
+ __field(unsigned long, curtarg )
+ __field(unsigned long, curactual )
+ __field(unsigned long, newtarg )
),
TP_fast_assign(
__entry->cpu_id = cpu_id;
__entry->load = load;
- __entry->curfreq = curfreq;
- __entry->targfreq = targfreq;
+ __entry->curtarg = curtarg;
+ __entry->curactual = curactual;
+ __entry->newtarg = newtarg;
),
- TP_printk("cpu=%lu load=%lu cur=%lu targ=%lu",
- __entry->cpu_id, __entry->load, __entry->curfreq,
- __entry->targfreq)
+ TP_printk("cpu=%lu load=%lu cur=%lu actual=%lu targ=%lu",
+ __entry->cpu_id, __entry->load, __entry->curtarg,
+ __entry->curactual, __entry->newtarg)
);
DEFINE_EVENT(loadeval, cpufreq_interactive_target,
TP_PROTO(unsigned long cpu_id, unsigned long load,
- unsigned long curfreq, unsigned long targfreq),
- TP_ARGS(cpu_id, load, curfreq, targfreq)
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
);
DEFINE_EVENT(loadeval, cpufreq_interactive_already,
TP_PROTO(unsigned long cpu_id, unsigned long load,
- unsigned long curfreq, unsigned long targfreq),
- TP_ARGS(cpu_id, load, curfreq, targfreq)
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
);
DEFINE_EVENT(loadeval, cpufreq_interactive_notyet,
TP_PROTO(unsigned long cpu_id, unsigned long load,
- unsigned long curfreq, unsigned long targfreq),
- TP_ARGS(cpu_id, load, curfreq, targfreq)
+ unsigned long curtarg, unsigned long curactual,
+ unsigned long newtarg),
+ TP_ARGS(cpu_id, load, curtarg, curactual, newtarg)
);
TRACE_EVENT(cpufreq_interactive_boost,
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 30/70] cpufreq: interactive: remove load since last speed change |
| Message-ID | <qogHp-8bo-49@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
The longer-term load since last speed change isn't terribly useful,
may delay recognition of dropping load, and would need forthcoming
changes to adjust load for changing CPU speeds. Drop it.
Change-Id: Ic3cbb0542cc3484617031787e03ed9bdd632dec1
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 34 ++++-----------------------------
1 file changed, 4 insertions(+), 30 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 6ea77a0..3d8e7b4 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -43,8 +43,6 @@ struct cpufreq_interactive_cpuinfo {
int timer_idlecancel;
u64 time_in_idle;
u64 time_in_idle_timestamp;
- u64 target_set_time;
- u64 target_set_time_in_idle;
struct cpufreq_policy *policy;
struct cpufreq_frequency_table *freq_table;
unsigned int target_freq;
@@ -238,7 +236,6 @@ static void cpufreq_interactive_timer(unsigned long data)
unsigned int delta_idle;
unsigned int delta_time;
int cpu_load;
- int load_since_change;
struct cpufreq_interactive_cpuinfo *pcpu =
&per_cpu(cpuinfo, data);
u64 now_idle;
@@ -266,23 +263,6 @@ static void cpufreq_interactive_timer(unsigned long data)
else
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)(now - pcpu->target_set_time);
-
- if ((delta_time == 0) || (delta_idle > delta_time))
- load_since_change = 0;
- else
- load_since_change =
- 100 * (delta_time - delta_idle) / delta_time;
-
- /*
- * Choose greater of short-term load (since last idle timer
- * started or timer function re-armed itself) or long-term load
- * (since last frequency change).
- */
- if (load_since_change > cpu_load)
- cpu_load = load_since_change;
-
if ((cpu_load >= go_hispeed_load || boost_val) &&
pcpu->target_freq < hispeed_freq)
new_freq = hispeed_freq;
@@ -335,8 +315,6 @@ static void cpufreq_interactive_timer(unsigned long data)
trace_cpufreq_interactive_target(data, cpu_load, pcpu->target_freq,
pcpu->policy->cur, new_freq);
- pcpu->target_set_time_in_idle = now_idle;
- pcpu->target_set_time = now;
pcpu->target_freq = new_freq;
spin_lock_irqsave(&speedchange_cpumask_lock, flags);
@@ -500,9 +478,8 @@ static void cpufreq_interactive_boost(void)
if (pcpu->target_freq < hispeed_freq) {
pcpu->target_freq = hispeed_freq;
cpumask_set_cpu(i, &speedchange_cpumask);
- pcpu->target_set_time_in_idle =
- get_cpu_idle_time_us(i, &pcpu->target_set_time);
- pcpu->hispeed_validate_time = pcpu->target_set_time;
+ pcpu->hispeed_validate_time =
+ ktime_to_us(ktime_get());
anyboost = 1;
}
@@ -815,14 +792,11 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
pcpu->policy = policy;
pcpu->target_freq = policy->cur;
pcpu->freq_table = freq_table;
- pcpu->target_set_time_in_idle =
- get_cpu_idle_time_us(j,
- &pcpu->target_set_time);
pcpu->floor_freq = pcpu->target_freq;
pcpu->floor_validate_time =
- pcpu->target_set_time;
+ ktime_to_us(ktime_get());
pcpu->hispeed_validate_time =
- pcpu->target_set_time;
+ pcpu->floor_validate_time;
pcpu->governor_enabled = 1;
smp_wmb();
pcpu->cpu_timer.expires =
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 40/70] cpufreq: interactive: fix deadlock on spinlock in timer |
| Message-ID | <qogHp-8bo-55@gated-at.bofh.it> |
| In reply to | #1256993 |
From: Todd Poynor <toddpoynor@google.com>
Need to use irqsave/restore spinlock calls to avoid a deadlock in calls
from the timer.
Change-Id: I15b6b590045ba1447e34ca7b5ff342723e53a605
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
drivers/cpufreq/cpufreq_interactive.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 51c34bf..e7f26aa 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -126,6 +126,7 @@ static void cpufreq_interactive_timer_resched(
struct cpufreq_interactive_cpuinfo *pcpu)
{
unsigned long expires = jiffies + usecs_to_jiffies(timer_rate);
+ unsigned long flags;
mod_timer_pinned(&pcpu->cpu_timer, expires);
if (timer_slack_val >= 0 && pcpu->target_freq > pcpu->policy->min) {
@@ -133,27 +134,28 @@ static void cpufreq_interactive_timer_resched(
mod_timer_pinned(&pcpu->cpu_slack_timer, expires);
}
- spin_lock(&pcpu->load_lock);
+ spin_lock_irqsave(&pcpu->load_lock, flags);
pcpu->time_in_idle =
get_cpu_idle_time_us(smp_processor_id(),
&pcpu->time_in_idle_timestamp);
pcpu->cputime_speedadj = 0;
pcpu->cputime_speedadj_timestamp = pcpu->time_in_idle_timestamp;
- spin_unlock(&pcpu->load_lock);
+ spin_unlock_irqrestore(&pcpu->load_lock, flags);
}
static unsigned int freq_to_targetload(unsigned int freq)
{
int i;
unsigned int ret;
+ unsigned long flags;
- spin_lock(&target_loads_lock);
+ spin_lock_irqsave(&target_loads_lock, flags);
for (i = 0; i < ntarget_loads - 1 && freq >= target_loads[i+1]; i += 2)
;
ret = target_loads[i];
- spin_unlock(&target_loads_lock);
+ spin_unlock_irqrestore(&target_loads_lock, flags);
return ret;
}
@@ -284,11 +286,11 @@ static void cpufreq_interactive_timer(unsigned long data)
if (!pcpu->governor_enabled)
goto exit;
- spin_lock(&pcpu->load_lock);
+ spin_lock_irqsave(&pcpu->load_lock, flags);
now = update_load(data);
delta_time = (unsigned int)(now - pcpu->cputime_speedadj_timestamp);
cputime_speedadj = pcpu->cputime_speedadj;
- spin_unlock(&pcpu->load_lock);
+ spin_unlock_irqrestore(&pcpu->load_lock, flags);
if (WARN_ON_ONCE(!delta_time))
goto rearm;
@@ -549,6 +551,7 @@ static int cpufreq_interactive_notifier(
struct cpufreq_freqs *freq = data;
struct cpufreq_interactive_cpuinfo *pcpu;
int cpu;
+ unsigned long flags;
if (val == CPUFREQ_POSTCHANGE) {
pcpu = &per_cpu(cpuinfo, freq->cpu);
@@ -562,9 +565,9 @@ static int cpufreq_interactive_notifier(
for_each_cpu(cpu, pcpu->policy->cpus) {
struct cpufreq_interactive_cpuinfo *pjcpu =
&per_cpu(cpuinfo, cpu);
- spin_lock(&pjcpu->load_lock);
+ spin_lock_irqsave(&pjcpu->load_lock, flags);
update_load(cpu);
- spin_unlock(&pjcpu->load_lock);
+ spin_unlock_irqrestore(&pjcpu->load_lock, flags);
}
up_read(&pcpu->enable_sem);
@@ -581,15 +584,16 @@ static ssize_t show_target_loads(
{
int i;
ssize_t ret = 0;
+ unsigned long flags;
- spin_lock(&target_loads_lock);
+ spin_lock_irqsave(&target_loads_lock, flags);
for (i = 0; i < ntarget_loads; i++)
ret += sprintf(buf + ret, "%u%s", target_loads[i],
i & 0x1 ? ":" : " ");
ret += sprintf(buf + ret, "\n");
- spin_unlock(&target_loads_lock);
+ spin_unlock_irqrestore(&target_loads_lock, flags);
return ret;
}
@@ -602,6 +606,7 @@ static ssize_t store_target_loads(
unsigned int *new_target_loads = NULL;
int ntokens = 1;
int i;
+ unsigned long flags;
cp = buf;
while ((cp = strpbrk(cp + 1, " :")))
@@ -631,12 +636,12 @@ static ssize_t store_target_loads(
if (i != ntokens)
goto err_inval;
- spin_lock(&target_loads_lock);
+ spin_lock_irqsave(&target_loads_lock, flags);
if (target_loads != default_target_loads)
kfree(target_loads);
target_loads = new_target_loads;
ntarget_loads = ntokens;
- spin_unlock(&target_loads_lock);
+ spin_unlock_irqrestore(&target_loads_lock, flags);
return count;
err_inval:
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Bálint Czobor <czoborbalint@gmail.com> |
|---|---|
| Date | 2015-10-27 19:00 +0100 |
| Subject | [PATCH 33/70] cpufreq: interactive: add timer slack to limit idle at speed > min |
| Message-ID | <qogHp-8bo-57@gated-at.bofh.it> |
| In reply to | #1256993 |
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/
[toc] | [prev] | [next] | [standalone]
Page 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
Back to top | Article view | linux.kernel
csiph-web