struct cpu_dbs_info_s {
        cputime64_t prev_cpu_idle;
+       cputime64_t prev_cpu_iowait;
        cputime64_t prev_cpu_wall;
        cputime64_t prev_cpu_nice;
        struct cpufreq_policy *cur_policy;
        return idle_time;
 }
 
+static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall)
+{
+       u64 iowait_time = get_cpu_iowait_time_us(cpu, wall);
+
+       if (iowait_time == -1ULL)
+               return 0;
+
+       return iowait_time;
+}
+
 /*
  * Find right freq to be set now with powersave_bias on.
  * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
 
        for_each_cpu(j, policy->cpus) {
                struct cpu_dbs_info_s *j_dbs_info;
-               cputime64_t cur_wall_time, cur_idle_time;
-               unsigned int idle_time, wall_time;
+               cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time;
+               unsigned int idle_time, wall_time, iowait_time;
                unsigned int load, load_freq;
                int freq_avg;
 
                j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
 
                cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+               cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time);
 
                wall_time = (unsigned int) cputime64_sub(cur_wall_time,
                                j_dbs_info->prev_cpu_wall);
                                j_dbs_info->prev_cpu_idle);
                j_dbs_info->prev_cpu_idle = cur_idle_time;
 
+               iowait_time = (unsigned int) cputime64_sub(cur_iowait_time,
+                               j_dbs_info->prev_cpu_iowait);
+               j_dbs_info->prev_cpu_iowait = cur_iowait_time;
+
                if (dbs_tuners_ins.ignore_nice) {
                        cputime64_t cur_nice;
                        unsigned long cur_nice_jiffies;
                        idle_time += jiffies_to_usecs(cur_nice_jiffies);
                }
 
+               /*
+                * For the purpose of ondemand, waiting for disk IO is an
+                * indication that you're performance critical, and not that
+                * the system is actually idle. So subtract the iowait time
+                * from the cpu idle time.
+                */
+
+               if (idle_time >= iowait_time)
+                       idle_time -= iowait_time;
+
                if (unlikely(!wall_time || wall_time < idle_time))
                        continue;