From: Dominik Brodowski From: "Pallipadi, Venkatesh" Check for lower limit of latency / sampling rate, and fix divide underflows. Signed-off-by: Andrew Morton --- 25-akpm/drivers/cpufreq/cpufreq_ondemand.c | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-) diff -puN drivers/cpufreq/cpufreq_ondemand.c~cpufreq-ondemand-prevent-various-divide-underflows drivers/cpufreq/cpufreq_ondemand.c --- 25/drivers/cpufreq/cpufreq_ondemand.c~cpufreq-ondemand-prevent-various-divide-underflows Thu Sep 30 17:18:12 2004 +++ 25-akpm/drivers/cpufreq/cpufreq_ondemand.c Thu Sep 30 17:18:12 2004 @@ -59,7 +59,7 @@ static unsigned int def_sampling_rat #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define DEF_SAMPLING_DOWN_FACTOR (10) #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); @@ -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 = 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) * - 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) { __cpufreq_driver_target(this_dbs_info->cur_policy, @@ -267,16 +269,23 @@ static void dbs_check_cpu(int cpu) idle_ticks = kstat_cpu(cpu).cpustat.idle - 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; this_dbs_info->prev_cpu_idle_down = kstat_cpu(cpu).cpustat.idle; freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * dbs_tuners_ins.sampling_down_factor; 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 ) { 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, this_dbs_info->cur_policy->cur - freq_down_step, CPUFREQ_RELATION_H); @@ -344,8 +353,14 @@ static int cpufreq_governor_dbs(struct c * is used for first time */ if (dbs_enable == 1) { + unsigned int latency; /* 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; dbs_tuners_ins.sampling_rate = def_sampling_rate; _