mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Bálint Czobor" <czoborbalint@gmail.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Viresh Kumar <viresh.kumar@linaro.org>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
	"Badhri Jagan Sridharan" <Badhri@google.com>,
	"Bálint Czobor" <czoborbalint@gmail.com>
Subject: [PATCH 61/70] cpufreq: interactive: restructure CPUFREQ_GOV_LIMITS
Date: Tue, 27 Oct 2015 18:30:49 +0100	[thread overview]
Message-ID: <1445967059-6897-61-git-send-email-czoborbalint@gmail.com> (raw)
In-Reply-To: <1445967059-6897-1-git-send-email-czoborbalint@gmail.com>

From: Badhri Jagan Sridharan <Badhri@google.com>

The cpufreq_interactive_timer gets cancelled and rescheduled
whenever the cpufreq_policy is changed. When the cpufreq policy is
changed at a rate faster than the sampling_rate of the interactive
governor, then the governor misses to change the target frequency
for long duration. The patch removes the need of cancelling the
timers when policy->min is changed.

Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
Change-Id: Ibd98d151e1c73b8bd969484583ff98ee9f1135ef
Signed-off-by: Bálint Czobor <czoborbalint@gmail.com>
---
 drivers/cpufreq/cpufreq_interactive.c |   48 ++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index 786fd01..0e3e45e 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -44,8 +44,10 @@ struct cpufreq_interactive_cpuinfo {
 	u64 cputime_speedadj_timestamp;
 	struct cpufreq_policy *policy;
 	struct cpufreq_frequency_table *freq_table;
+	spinlock_t target_freq_lock; /*protects target freq */
 	unsigned int target_freq;
 	unsigned int floor_freq;
+	unsigned int max_freq;
 	u64 floor_validate_time;
 	u64 hispeed_validate_time;
 	struct rw_semaphore enable_sem;
@@ -358,6 +360,7 @@ static void cpufreq_interactive_timer(unsigned long data)
 	if (WARN_ON_ONCE(!delta_time))
 		goto rearm;
 
+	spin_lock_irqsave(&pcpu->target_freq_lock, flags);
 	do_div(cputime_speedadj, delta_time);
 	loadadjfreq = (unsigned int)cputime_speedadj * 100;
 	cpu_load = loadadjfreq / pcpu->target_freq;
@@ -383,6 +386,7 @@ static void cpufreq_interactive_timer(unsigned long data)
 		trace_cpufreq_interactive_notyet(
 			data, cpu_load, pcpu->target_freq,
 			pcpu->policy->cur, new_freq);
+		spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
 		goto rearm;
 	}
 
@@ -390,8 +394,10 @@ static void cpufreq_interactive_timer(unsigned long data)
 
 	if (cpufreq_frequency_table_target(pcpu->policy, pcpu->freq_table,
 					   new_freq, CPUFREQ_RELATION_L,
-					   &index))
+					   &index)) {
+		spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
 		goto rearm;
+	}
 
 	new_freq = pcpu->freq_table[index].frequency;
 
@@ -405,6 +411,7 @@ static void cpufreq_interactive_timer(unsigned long data)
 			trace_cpufreq_interactive_notyet(
 				data, cpu_load, pcpu->target_freq,
 				pcpu->policy->cur, new_freq);
+			spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
 			goto rearm;
 		}
 	}
@@ -426,6 +433,7 @@ static void cpufreq_interactive_timer(unsigned long data)
 		trace_cpufreq_interactive_already(
 			data, cpu_load, pcpu->target_freq,
 			pcpu->policy->cur, new_freq);
+		spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
 		goto rearm_if_notmax;
 	}
 
@@ -433,6 +441,7 @@ static void cpufreq_interactive_timer(unsigned long data)
 					 pcpu->policy->cur, new_freq);
 
 	pcpu->target_freq = new_freq;
+	spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
 	spin_lock_irqsave(&speedchange_cpumask_lock, flags);
 	cpumask_set_cpu(data, &speedchange_cpumask);
 	spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
@@ -576,16 +585,17 @@ static void cpufreq_interactive_boost(void)
 {
 	int i;
 	int anyboost = 0;
-	unsigned long flags;
+	unsigned long flags[2];
 	struct cpufreq_interactive_cpuinfo *pcpu;
 	struct cpufreq_interactive_tunables *tunables;
 
-	spin_lock_irqsave(&speedchange_cpumask_lock, flags);
+	spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);
 
 	for_each_online_cpu(i) {
 		pcpu = &per_cpu(cpuinfo, i);
 		tunables = pcpu->policy->governor_data;
 
+		spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
 		if (pcpu->target_freq < tunables->hispeed_freq) {
 			pcpu->target_freq = tunables->hispeed_freq;
 			cpumask_set_cpu(i, &speedchange_cpumask);
@@ -601,9 +611,10 @@ static void cpufreq_interactive_boost(void)
 
 		pcpu->floor_freq = tunables->hispeed_freq;
 		pcpu->floor_validate_time = ktime_to_us(ktime_get());
+		spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]);
 	}
 
-	spin_unlock_irqrestore(&speedchange_cpumask_lock, flags);
+	spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);
 
 	if (anyboost)
 		wake_up_process(speedchange_task);
@@ -1114,6 +1125,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
 	struct cpufreq_interactive_cpuinfo *pcpu;
 	struct cpufreq_frequency_table *freq_table;
 	struct cpufreq_interactive_tunables *tunables;
+	unsigned long flags;
 
 	if (have_governor_per_policy())
 		tunables = policy->governor_data;
@@ -1215,6 +1227,7 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
 				ktime_to_us(ktime_get());
 			pcpu->hispeed_validate_time =
 				pcpu->floor_validate_time;
+			pcpu->max_freq = policy->max;
 			down_write(&pcpu->enable_sem);
 			del_timer_sync(&pcpu->cpu_timer);
 			del_timer_sync(&pcpu->cpu_slack_timer);
@@ -1250,29 +1263,37 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
 		for_each_cpu(j, policy->cpus) {
 			pcpu = &per_cpu(cpuinfo, j);
 
-			/* hold write semaphore to avoid race */
-			down_write(&pcpu->enable_sem);
+			down_read(&pcpu->enable_sem);
 			if (pcpu->governor_enabled == 0) {
-				up_write(&pcpu->enable_sem);
+				up_read(&pcpu->enable_sem);
 				continue;
 			}
 
-			/* update target_freq firstly */
+			spin_lock_irqsave(&pcpu->target_freq_lock, flags);
 			if (policy->max < pcpu->target_freq)
 				pcpu->target_freq = policy->max;
 			else if (policy->min > pcpu->target_freq)
 				pcpu->target_freq = policy->min;
 
-			/* Reschedule timer.
+			spin_unlock_irqrestore(&pcpu->target_freq_lock, flags);
+			up_read(&pcpu->enable_sem);
+
+			/* Reschedule timer only if policy->max is raised.
 			 * Delete the timers, else the timer callback may
 			 * return without re-arm the timer when failed
 			 * acquire the semaphore. This race may cause timer
 			 * stopped unexpectedly.
 			 */
-			del_timer_sync(&pcpu->cpu_timer);
-			del_timer_sync(&pcpu->cpu_slack_timer);
-			cpufreq_interactive_timer_start(tunables, j);
-			up_write(&pcpu->enable_sem);
+
+			if (policy->max > pcpu->max_freq) {
+				down_write(&pcpu->enable_sem);
+				del_timer_sync(&pcpu->cpu_timer);
+				del_timer_sync(&pcpu->cpu_slack_timer);
+				cpufreq_interactive_timer_start(tunables, j);
+				up_write(&pcpu->enable_sem);
+			}
+
+			pcpu->max_freq = policy->max;
 		}
 		break;
 	}
@@ -1308,6 +1329,7 @@ static int __init cpufreq_interactive_init(void)
 		init_timer(&pcpu->cpu_slack_timer);
 		pcpu->cpu_slack_timer.function = cpufreq_interactive_nop_timer;
 		spin_lock_init(&pcpu->load_lock);
+		spin_lock_init(&pcpu->target_freq_lock);
 		init_rwsem(&pcpu->enable_sem);
 	}
 
-- 
1.7.9.5


  parent reply	other threads:[~2015-10-27 17:38 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-27 17:29 [PATCH 01/70] cpufreq: interactive: New 'interactive' governor Bálint Czobor
2015-10-27 17:29 ` [PATCH 02/70] cpufreq interactive governor: event tracing Bálint Czobor
2015-10-27 17:29 ` [PATCH 03/70] cpufreq: interactive: apply intermediate load to max speed not current Bálint Czobor
2015-10-27 17:29 ` [PATCH 04/70] cpufreq: interactive: set at least hispeed when above hispeed load Bálint Czobor
2015-10-27 17:29 ` [PATCH 05/70] cpufreq: interactive: don't drop speed if recently at higher load Bálint Czobor
2015-10-27 17:29 ` [PATCH 06/70] cpufreq: interactive: configurable delay before raising above hispeed Bálint Czobor
2015-10-27 17:29 ` [PATCH 07/70] cpufreq: interactive: adjust code and documentation to match Bálint Czobor
2015-10-27 17:29 ` [PATCH 08/70] cpufreq: interactive: base hispeed bump on target freq, not actual Bálint Czobor
2015-10-27 17:29 ` [PATCH 09/70] cpufreq: interactive: Separate speed target revalidate time and initial set time Bálint Czobor
2015-10-27 17:29 ` [PATCH 10/70] cpufreq: interactive: Boost frequency on touchscreen input Bálint Czobor
2015-10-27 17:29 ` [PATCH 11/70] cpufreq: interactive: remove unused target_validate_time_in_idle Bálint Czobor
2015-10-27 17:30 ` [PATCH 12/70] cpufreq: interactive: Add sysfs boost interface for hints from userspace Bálint Czobor
2015-10-27 17:30 ` [PATCH 13/70] cpufreq: interactive: set floor for boosted speed Bálint Czobor
2015-10-27 17:30 ` [PATCH 14/70] cpufreq: interactive: add boost pulse interface Bálint Czobor
2015-10-27 17:30 ` [PATCH 15/70] cpufreq-interactive: Compile fixup Bálint Czobor
2015-10-27 17:30 ` [PATCH 16/70] cpufreq: interactive: restart above_hispeed_delay at each hispeed load Bálint Czobor
2015-10-27 17:30 ` [PATCH 17/70] cpufreq: interactive: take idle notifications only when active Bálint Czobor
2015-10-27 20:56   ` kbuild test robot
2015-10-27 17:30 ` [PATCH 18/70] cpufreq: interactive: keep freezer happy when not current governor Bálint Czobor
2015-10-27 17:30 ` [PATCH 19/70] cpufreq: interactive: handle speed up and down in the realtime task Bálint Czobor
2015-10-27 17:30 ` [PATCH 20/70] cpufreq: interactive: remove input_boost handling Bálint Czobor
2015-10-27 17:30 ` [PATCH 21/70] cpufreq: interactive: always limit initial speed bump to hispeed Bálint Czobor
2015-10-27 17:30 ` [PATCH 22/70] cpufreq: interactive: run at fraction of hispeed_freq when load is low Bálint Czobor
2015-10-27 17:30 ` [PATCH 23/70] cpufreq: interactive: pin timers to associated CPU Bálint Czobor
2015-10-27 17:30 ` [PATCH 24/70] cpufreq: interactive: use deferrable timer by default Bálint Czobor
2015-10-27 17:30 ` [PATCH 25/70] cpufreq: interactive: kick timer on idle exit past expiry Bálint Czobor
2015-10-27 17:30 ` [PATCH 26/70] cpufreq: interactive: trace actual speed in target speed decisions Bálint Czobor
2015-10-27 17:30 ` [PATCH 27/70] cpufreq: interactive: change speed according to current speed and target load Bálint Czobor
2015-10-27 17:30 ` [PATCH 28/70] cpufreq: interactive: apply above_hispeed_delay to each step above hispeed Bálint Czobor
2015-10-27 17:30 ` [PATCH 29/70] cpufreq: interactive: allow arbitrary speed / target load mappings Bálint Czobor
2015-10-27 17:30 ` [PATCH 30/70] cpufreq: interactive: remove load since last speed change Bálint Czobor
2015-10-27 17:30 ` [PATCH 31/70] cpufreq: interactive: adjust load for changes in speed Bálint Czobor
2015-10-27 17:30 ` [PATCH 32/70] cpufreq: interactive: specify duration of CPU speed boost pulse Bálint Czobor
2015-10-27 17:30 ` [PATCH 33/70] cpufreq: interactive: add timer slack to limit idle at speed > min Bálint Czobor
2015-10-27 17:30 ` [PATCH 34/70] cpufreq: interactive: fix boosting logic Bálint Czobor
2015-10-27 17:30 ` [PATCH 35/70] cpufreq: interactive: fix racy timer stopping Bálint Czobor
2015-10-27 17:30 ` [PATCH 36/70] cpufreq: interactive: fix race on timer restart on governor start Bálint Czobor
2015-10-27 17:30 ` [PATCH 37/70] cpufreq: interactive: default go_hispeed_load 99%, doc updates Bálint Czobor
2015-10-27 17:30 ` [PATCH 38/70] cpufreq: interactive: init default values at compile time Bálint Czobor
2015-10-27 17:30 ` [PATCH 39/70] cpufreq: interactive: don't handle transition notification if not enabled Bálint Czobor
2015-10-27 17:30 ` [PATCH 40/70] cpufreq: interactive: fix deadlock on spinlock in timer Bálint Czobor
2015-10-27 17:30 ` [PATCH 41/70] cpufreq: interactive: fix race on governor start/stop Bálint Czobor
2015-10-27 17:30 ` [PATCH 42/70] cpufreq: interactive: allow arbitrary speed / delay mappings Bálint Czobor
2015-10-27 17:30 ` [PATCH 43/70] cpufreq: interactive: add io_is_busy interface Bálint Czobor
2015-10-27 17:30 ` [PATCH 44/70] cpufreq: interactive: fix crash on error paths in get_tokenized_data Bálint Czobor
2015-10-27 17:30 ` [PATCH 45/70] cpufreq: interactive: base above_hispeed_delay on target freq, not current Bálint Czobor
2015-10-27 17:30 ` [PATCH 46/70] cpufreq: interactive: fix uninitialized spinlock Bálint Czobor
2015-10-27 17:30 ` [PATCH 47/70] cpufreq: interactive: handle errors from cpufreq_frequency_table_target Bálint Czobor
2015-10-27 17:30 ` [PATCH 48/70] cpufreq: interactive: reduce chance of zero time delta on load eval Bálint Czobor
2015-10-27 17:30 ` [PATCH 49/70] cpufreq: interactive: avoid underflow on active time calculation Bálint Czobor
2015-10-27 17:30 ` [PATCH 50/70] cpufreq: interactive: fix race on cpufreq TRANSITION notifier Bálint Czobor
2015-10-27 17:30 ` [PATCH 51/70] cpufreq: interactive: resched timer if max freq raised Bálint Czobor
2015-10-27 17:30 ` [PATCH 52/70] cpufreq: interactive: fix show_target_loads and show_above_hispeed_delay Bálint Czobor
2015-10-27 17:30 ` [PATCH 53/70] cpufreq: interactive: Remove unnecessary cpu_online() check Bálint Czobor
2015-10-27 17:30 ` [PATCH 54/70] cpufreq: interactive: Move definition of cpufreq_gov_interactive downwards Bálint Czobor
2015-10-27 17:30 ` [PATCH 55/70] cpufreq: Interactive: Implement per policy instances of governor Bálint Czobor
2015-10-27 17:30 ` [PATCH 56/70] cpufreq: interactive: delete timers for GOV_START Bálint Czobor
2015-10-27 17:30 ` [PATCH 57/70] cpufreq: interactive: fix compiling warnings Bálint Czobor
2015-10-27 17:30 ` [PATCH 58/70] cpufreq: interactive: fix NULL pointer dereference at sysfs ops Bálint Czobor
2015-10-27 17:30 ` [PATCH 59/70] cpufreq: interactive: Use generic get_cpu_idle_time() from cpufreq.c Bálint Czobor
2015-10-27 17:30 ` [PATCH 60/70] cpufreq: interactive: hold reference on global cpufreq kobject if needed Bálint Czobor
2015-10-27 17:30 ` Bálint Czobor [this message]
2015-10-27 17:30 ` [PATCH 62/70] cpufreq: interactive: turn boost_pulse off on boost off Bálint Czobor
2015-10-27 17:30 ` [PATCH 63/70] cpufreq: interactive: remove compilation error from commit 49cc72365fb7ee87762a7ccc6a32ef68627216c5 Bálint Czobor
2015-10-27 17:30 ` [PATCH 64/70] cpufreq: interactive: prevents the frequency to directly raise above the hispeed_freq from a lower frequency Bálint Czobor
2015-10-27 17:30 ` [PATCH 65/70] cpufreq: interactive: make common_tunables static Bálint Czobor
2015-10-27 17:30 ` [PATCH 66/70] cpufreq: interactive: Fix compile errors in accordance with changes from 3.14 to 3.18 Bálint Czobor
2015-10-28  2:15   ` kbuild test robot
2015-10-27 17:30 ` [PATCH 67/70] cpufreq: interactive: Put global cpufreq kobject on failure Bálint Czobor
2015-10-27 17:30 ` [PATCH 68/70] subsystem: CPU FREQUENCY DRIVERS- Set cpu_load calculation on current frequency Bálint Czobor
2015-10-27 17:30 ` [PATCH 69/70] cpufreq: interactive: Don't set floor_validate_time during boost Bálint Czobor
2015-10-27 17:30 ` [PATCH 70/70] cpufreq: interactive: Round up timer_rate to match jiffy Bálint Czobor
2015-10-27 20:44 ` [PATCH 01/70] cpufreq: interactive: New 'interactive' governor kbuild test robot
2015-10-28  0:59 ` Rafael J. Wysocki
2015-10-28  3:00   ` Viresh Kumar
     [not found]     ` <CAL6DFdfsDTtkkpLJ7kg9L9rFh+Ho6DC7x9a+F3x9DydvXHfbPQ@mail.gmail.com>
     [not found]       ` <CAL6DFdeSbzM5go==i8Z_CJ19VrAMWVVWF5NuD+VNMONaPK5zLA@mail.gmail.com>
2015-10-29  1:42         ` Viresh Kumar
2015-11-02 14:02     ` Peter Zijlstra
2015-11-02 18:06       ` Steve Muckle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1445967059-6897-61-git-send-email-czoborbalint@gmail.com \
    --to=czoborbalint@gmail.com \
    --cc=Badhri@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®