aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMyungJoo Ham <myungjoo.ham@samsung.com>2012-02-29 03:54:41 -0500
committerDave Jones <davej@redhat.com>2012-02-29 22:24:40 -0500
commitfd0ef7a0583b9af3efeb7b1f965ea80b5ff70cdf (patch)
tree3ed8deaecc23fd71d5c777c962c9833f071bc7e7 /drivers
parent34ee55075265d68ca858f2426e165733664385b4 (diff)
[CPUFREQ] CPUfreq ondemand: update sampling rate without waiting for next sampling
When a new sampling rate is shorter than the current one, (e.g., 1 sec --> 10 ms) regardless how short the new one is, the current ondemand mechanism wait for the previously set timer to be expired. For example, if the user has just expressed that the sampling rate should be 10 ms from now and the previous was 1000 ms, the new rate may become effective 999 ms later, which could be not acceptable for the user if the user has intended to speed up sampling because the system is expected to react to CPU load fluctuation quickly from __now__. In order to address this issue, we need to cancel the previously set timer (schedule_delayed_work) and reset the timer if resetting timer is expected to trigger the delayed_work ealier. Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index c3e0652520a1..836e9b062e5e 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -257,6 +257,62 @@ show_one(sampling_down_factor, sampling_down_factor);
257show_one(ignore_nice_load, ignore_nice); 257show_one(ignore_nice_load, ignore_nice);
258show_one(powersave_bias, powersave_bias); 258show_one(powersave_bias, powersave_bias);
259 259
260/**
261 * update_sampling_rate - update sampling rate effective immediately if needed.
262 * @new_rate: new sampling rate
263 *
264 * If new rate is smaller than the old, simply updaing
265 * dbs_tuners_int.sampling_rate might not be appropriate. For example,
266 * if the original sampling_rate was 1 second and the requested new sampling
267 * rate is 10 ms because the user needs immediate reaction from ondemand
268 * governor, but not sure if higher frequency will be required or not,
269 * then, the governor may change the sampling rate too late; up to 1 second
270 * later. Thus, if we are reducing the sampling rate, we need to make the
271 * new value effective immediately.
272 */
273static void update_sampling_rate(unsigned int new_rate)
274{
275 int cpu;
276
277 dbs_tuners_ins.sampling_rate = new_rate
278 = max(new_rate, min_sampling_rate);
279
280 for_each_online_cpu(cpu) {
281 struct cpufreq_policy *policy;
282 struct cpu_dbs_info_s *dbs_info;
283 unsigned long next_sampling, appointed_at;
284
285 policy = cpufreq_cpu_get(cpu);
286 if (!policy)
287 continue;
288 dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu);
289 cpufreq_cpu_put(policy);
290
291 mutex_lock(&dbs_info->timer_mutex);
292
293 if (!delayed_work_pending(&dbs_info->work)) {
294 mutex_unlock(&dbs_info->timer_mutex);
295 continue;
296 }
297
298 next_sampling = jiffies + usecs_to_jiffies(new_rate);
299 appointed_at = dbs_info->work.timer.expires;
300
301
302 if (time_before(next_sampling, appointed_at)) {
303
304 mutex_unlock(&dbs_info->timer_mutex);
305 cancel_delayed_work_sync(&dbs_info->work);
306 mutex_lock(&dbs_info->timer_mutex);
307
308 schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work,
309 usecs_to_jiffies(new_rate));
310
311 }
312 mutex_unlock(&dbs_info->timer_mutex);
313 }
314}
315
260static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, 316static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
261 const char *buf, size_t count) 317 const char *buf, size_t count)
262{ 318{
@@ -265,7 +321,7 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
265 ret = sscanf(buf, "%u", &input); 321 ret = sscanf(buf, "%u", &input);
266 if (ret != 1) 322 if (ret != 1)
267 return -EINVAL; 323 return -EINVAL;
268 dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate); 324 update_sampling_rate(input);
269 return count; 325 return count;
270} 326}
271 327