Commit 545afd16 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] cpufreq: ondemand: prevent various divide underflows

From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>

Check for lower limit of latency / sampling rate, and fix divide
underflows.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 9b2f06f1
...@@ -59,7 +59,7 @@ static unsigned int def_sampling_rate; ...@@ -59,7 +59,7 @@ static unsigned int def_sampling_rate;
#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
#define DEF_SAMPLING_DOWN_FACTOR (10) #define DEF_SAMPLING_DOWN_FACTOR (10)
#define TRANSITION_LATENCY_LIMIT (10 * 1000) #define TRANSITION_LATENCY_LIMIT (10 * 1000)
#define sampling_rate_in_HZ(x) ((x * HZ) / (1000 * 1000)) #define sampling_rate_in_HZ(x) (((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000)))
static void do_dbs_timer(void *data); static void do_dbs_timer(void *data);
...@@ -248,8 +248,10 @@ static void dbs_check_cpu(int cpu) ...@@ -248,8 +248,10 @@ static void dbs_check_cpu(int cpu)
this_dbs_info->prev_cpu_idle_up; this_dbs_info->prev_cpu_idle_up;
this_dbs_info->prev_cpu_idle_up = kstat_cpu(cpu).cpustat.idle; this_dbs_info->prev_cpu_idle_up = kstat_cpu(cpu).cpustat.idle;
/* Scale idle ticks by 100 and compare with up and down ticks */
idle_ticks *= 100;
up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate) / 100; sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
if (idle_ticks < up_idle_ticks) { if (idle_ticks < up_idle_ticks) {
__cpufreq_driver_target(this_dbs_info->cur_policy, __cpufreq_driver_target(this_dbs_info->cur_policy,
...@@ -267,16 +269,23 @@ static void dbs_check_cpu(int cpu) ...@@ -267,16 +269,23 @@ static void dbs_check_cpu(int cpu)
idle_ticks = kstat_cpu(cpu).cpustat.idle - idle_ticks = kstat_cpu(cpu).cpustat.idle -
this_dbs_info->prev_cpu_idle_down; this_dbs_info->prev_cpu_idle_down;
/* Scale idle ticks by 100 and compare with up and down ticks */
idle_ticks *= 100;
down_skip[cpu] = 0; down_skip[cpu] = 0;
this_dbs_info->prev_cpu_idle_down = kstat_cpu(cpu).cpustat.idle; this_dbs_info->prev_cpu_idle_down = kstat_cpu(cpu).cpustat.idle;
freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
dbs_tuners_ins.sampling_down_factor; dbs_tuners_ins.sampling_down_factor;
down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
sampling_rate_in_HZ(freq_down_sampling_rate) / 100; sampling_rate_in_HZ(freq_down_sampling_rate);
if (idle_ticks > down_idle_ticks ) { if (idle_ticks > down_idle_ticks ) {
freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100; freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100;
/* max freq cannot be less than 100. But who knows.... */
if (unlikely(freq_down_step == 0))
freq_down_step = 5;
__cpufreq_driver_target(this_dbs_info->cur_policy, __cpufreq_driver_target(this_dbs_info->cur_policy,
this_dbs_info->cur_policy->cur - freq_down_step, this_dbs_info->cur_policy->cur - freq_down_step,
CPUFREQ_RELATION_H); CPUFREQ_RELATION_H);
...@@ -344,8 +353,14 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, ...@@ -344,8 +353,14 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
* is used for first time * is used for first time
*/ */
if (dbs_enable == 1) { if (dbs_enable == 1) {
unsigned int latency;
/* policy latency is in nS. Convert it to uS first */ /* policy latency is in nS. Convert it to uS first */
def_sampling_rate = (policy->cpuinfo.transition_latency / 1000) *
latency = policy->cpuinfo.transition_latency;
if (latency < 1000)
latency = 1000;
def_sampling_rate = (latency / 1000) *
DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
dbs_tuners_ins.sampling_rate = def_sampling_rate; dbs_tuners_ins.sampling_rate = def_sampling_rate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment