diff options
author | venkatesh.pallipadi@intel.com <venkatesh.pallipadi@intel.com> | 2008-08-04 14:59:08 -0400 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2008-10-09 13:52:43 -0400 |
commit | c43aa3bd99a67009a167430e80c5fde6f37288d8 (patch) | |
tree | 41e0aa9b864aa6a3d214c1c5ad52bc1f934e1423 /drivers/cpufreq | |
parent | bf0b90e357c883e8efd72954432efe652de74c76 (diff) |
[CPUFREQ][2/6] cpufreq: Change load calculation in ondemand for software coordination
Change the load calculation algorithm in ondemand to work well with software
coordination of frequency across the dependent cpus.
Multiply individual CPU utilization with the average freq of that logical CPU
during the measurement interval (using getavg call). And find the max CPU
utilization number in terms of CPU freq. That number is then used to
get to the target freq for next sampling interval.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r-- | drivers/cpufreq/cpufreq_ondemand.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index f56debd9a8d7..42fcb146ba22 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -334,9 +334,7 @@ static struct attribute_group dbs_attr_group = { | |||
334 | 334 | ||
335 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 335 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
336 | { | 336 | { |
337 | unsigned int idle_ticks, total_ticks; | 337 | unsigned int max_load_freq; |
338 | unsigned int load = 0; | ||
339 | cputime64_t cur_jiffies; | ||
340 | 338 | ||
341 | struct cpufreq_policy *policy; | 339 | struct cpufreq_policy *policy; |
342 | unsigned int j; | 340 | unsigned int j; |
@@ -346,13 +344,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
346 | 344 | ||
347 | this_dbs_info->freq_lo = 0; | 345 | this_dbs_info->freq_lo = 0; |
348 | policy = this_dbs_info->cur_policy; | 346 | policy = this_dbs_info->cur_policy; |
349 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | ||
350 | total_ticks = (unsigned int) cputime64_sub(cur_jiffies, | ||
351 | this_dbs_info->prev_cpu_wall); | ||
352 | this_dbs_info->prev_cpu_wall = get_jiffies_64(); | ||
353 | 347 | ||
354 | if (!total_ticks) | ||
355 | return; | ||
356 | /* | 348 | /* |
357 | * Every sampling_rate, we check, if current idle time is less | 349 | * Every sampling_rate, we check, if current idle time is less |
358 | * than 20% (default), then we try to increase frequency | 350 | * than 20% (default), then we try to increase frequency |
@@ -365,27 +357,46 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
365 | * 5% (default) of current frequency | 357 | * 5% (default) of current frequency |
366 | */ | 358 | */ |
367 | 359 | ||
368 | /* Get Idle Time */ | 360 | /* Get Absolute Load - in terms of freq */ |
369 | idle_ticks = UINT_MAX; | 361 | max_load_freq = 0; |
362 | |||
370 | for_each_cpu_mask_nr(j, policy->cpus) { | 363 | for_each_cpu_mask_nr(j, policy->cpus) { |
371 | cputime64_t total_idle_ticks; | ||
372 | unsigned int tmp_idle_ticks; | ||
373 | struct cpu_dbs_info_s *j_dbs_info; | 364 | struct cpu_dbs_info_s *j_dbs_info; |
365 | cputime64_t cur_wall_time, cur_idle_time; | ||
366 | unsigned int idle_time, wall_time; | ||
367 | unsigned int load, load_freq; | ||
368 | int freq_avg; | ||
374 | 369 | ||
375 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 370 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
376 | total_idle_ticks = get_cpu_idle_time(j); | 371 | cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); |
377 | tmp_idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, | 372 | wall_time = (unsigned int) cputime64_sub(cur_wall_time, |
373 | j_dbs_info->prev_cpu_wall); | ||
374 | j_dbs_info->prev_cpu_wall = cur_wall_time; | ||
375 | |||
376 | cur_idle_time = get_cpu_idle_time(j); | ||
377 | idle_time = (unsigned int) cputime64_sub(cur_idle_time, | ||
378 | j_dbs_info->prev_cpu_idle); | 378 | j_dbs_info->prev_cpu_idle); |
379 | j_dbs_info->prev_cpu_idle = total_idle_ticks; | 379 | j_dbs_info->prev_cpu_idle = cur_idle_time; |
380 | 380 | ||
381 | if (tmp_idle_ticks < idle_ticks) | 381 | if (unlikely(wall_time <= idle_time || |
382 | idle_ticks = tmp_idle_ticks; | 382 | (cputime_to_msecs(wall_time) < |
383 | dbs_tuners_ins.sampling_rate / (2 * 1000)))) { | ||
384 | continue; | ||
385 | } | ||
386 | |||
387 | load = 100 * (wall_time - idle_time) / wall_time; | ||
388 | |||
389 | freq_avg = __cpufreq_driver_getavg(policy, j); | ||
390 | if (freq_avg <= 0) | ||
391 | freq_avg = policy->cur; | ||
392 | |||
393 | load_freq = load * freq_avg; | ||
394 | if (load_freq > max_load_freq) | ||
395 | max_load_freq = load_freq; | ||
383 | } | 396 | } |
384 | if (likely(total_ticks > idle_ticks)) | ||
385 | load = (100 * (total_ticks - idle_ticks)) / total_ticks; | ||
386 | 397 | ||
387 | /* Check for frequency increase */ | 398 | /* Check for frequency increase */ |
388 | if (load > dbs_tuners_ins.up_threshold) { | 399 | if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { |
389 | /* if we are already at full speed then break out early */ | 400 | /* if we are already at full speed then break out early */ |
390 | if (!dbs_tuners_ins.powersave_bias) { | 401 | if (!dbs_tuners_ins.powersave_bias) { |
391 | if (policy->cur == policy->max) | 402 | if (policy->cur == policy->max) |
@@ -412,15 +423,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
412 | * can support the current CPU usage without triggering the up | 423 | * can support the current CPU usage without triggering the up |
413 | * policy. To be safe, we focus 10 points under the threshold. | 424 | * policy. To be safe, we focus 10 points under the threshold. |
414 | */ | 425 | */ |
415 | if (load < (dbs_tuners_ins.up_threshold - 10)) { | 426 | if (max_load_freq < (dbs_tuners_ins.up_threshold - 10) * policy->cur) { |
416 | unsigned int freq_next, freq_cur; | 427 | unsigned int freq_next; |
417 | 428 | freq_next = max_load_freq / (dbs_tuners_ins.up_threshold - 10); | |
418 | freq_cur = __cpufreq_driver_getavg(policy, policy->cpu); | ||
419 | if (!freq_cur) | ||
420 | freq_cur = policy->cur; | ||
421 | |||
422 | freq_next = (freq_cur * load) / | ||
423 | (dbs_tuners_ins.up_threshold - 10); | ||
424 | 429 | ||
425 | if (!dbs_tuners_ins.powersave_bias) { | 430 | if (!dbs_tuners_ins.powersave_bias) { |
426 | __cpufreq_driver_target(policy, freq_next, | 431 | __cpufreq_driver_target(policy, freq_next, |