aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_conservative.c
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@linaro.org>2012-12-27 09:55:41 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-02-01 18:01:13 -0500
commit66df2a01dfd715636f5c86f7afd05362e7e3fddd (patch)
tree419905e3de1dcb00787e277b85b2d8fcab350092 /drivers/cpufreq/cpufreq_conservative.c
parentda53d61e21a5869b2e44247bb37deb8be387e063 (diff)
cpufreq: conservative: call dbs_check_cpu only when necessary
Modify conservative timer to not resample CPU utilization if recently sampled from another SW coordinated core. Signed-off-by: Fabio Baltieri <fabio.baltieri@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/cpufreq_conservative.c')
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index b9d7f14d7d3d..5d8e8942ec97 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -111,22 +111,57 @@ static void cs_check_cpu(int cpu, unsigned int load)
111 } 111 }
112} 112}
113 113
114static void cs_dbs_timer(struct work_struct *work) 114static void cs_timer_update(struct cs_cpu_dbs_info_s *dbs_info, bool sample,
115 struct delayed_work *dw)
115{ 116{
116 struct cs_cpu_dbs_info_s *dbs_info = container_of(work,
117 struct cs_cpu_dbs_info_s, cdbs.work.work);
118 unsigned int cpu = dbs_info->cdbs.cpu; 117 unsigned int cpu = dbs_info->cdbs.cpu;
119 int delay = delay_for_sampling_rate(cs_tuners.sampling_rate); 118 int delay = delay_for_sampling_rate(cs_tuners.sampling_rate);
120 119
120 if (sample)
121 dbs_check_cpu(&cs_dbs_data, cpu);
122
123 schedule_delayed_work_on(smp_processor_id(), dw, delay);
124}
125
126static void cs_timer_coordinated(struct cs_cpu_dbs_info_s *dbs_info_local,
127 struct delayed_work *dw)
128{
129 struct cs_cpu_dbs_info_s *dbs_info;
130 ktime_t time_now;
131 s64 delta_us;
132 bool sample = true;
133
134 /* use leader CPU's dbs_info */
135 dbs_info = &per_cpu(cs_cpu_dbs_info, dbs_info_local->cdbs.cpu);
121 mutex_lock(&dbs_info->cdbs.timer_mutex); 136 mutex_lock(&dbs_info->cdbs.timer_mutex);
122 137
123 dbs_check_cpu(&cs_dbs_data, cpu); 138 time_now = ktime_get();
139 delta_us = ktime_us_delta(time_now, dbs_info->cdbs.time_stamp);
124 140
125 schedule_delayed_work_on(smp_processor_id(), &dbs_info->cdbs.work, 141 /* Do nothing if we recently have sampled */
126 delay); 142 if (delta_us < (s64)(cs_tuners.sampling_rate / 2))
143 sample = false;
144 else
145 dbs_info->cdbs.time_stamp = time_now;
146
147 cs_timer_update(dbs_info, sample, dw);
127 mutex_unlock(&dbs_info->cdbs.timer_mutex); 148 mutex_unlock(&dbs_info->cdbs.timer_mutex);
128} 149}
129 150
151static void cs_dbs_timer(struct work_struct *work)
152{
153 struct delayed_work *dw = to_delayed_work(work);
154 struct cs_cpu_dbs_info_s *dbs_info = container_of(work,
155 struct cs_cpu_dbs_info_s, cdbs.work.work);
156
157 if (dbs_sw_coordinated_cpus(&dbs_info->cdbs)) {
158 cs_timer_coordinated(dbs_info, dw);
159 } else {
160 mutex_lock(&dbs_info->cdbs.timer_mutex);
161 cs_timer_update(dbs_info, true, dw);
162 mutex_unlock(&dbs_info->cdbs.timer_mutex);
163 }
164}
130static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 165static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
131 void *data) 166 void *data)
132{ 167{