cpufreq: governors: Calculate iowait time only when necessary
PATCH 1/1 cpufreq: governors: Calculate iowait time only when necessary
Currently we always calculate the CPU iowait time and add it to idle time. If we are in ondemand and we use io_is_busy, we re-calculate iowait time and we subtract it from idle time.
With this patch iowait time is calculated only when necessary avoiding the double call to get_cpu_iowait_time_us. We use a parameter in function get_cpu_idle_time to distinguish when the iowait time will be added to idle time or not, without the need of keeping the prev_io_wait.
--- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_governor.c | 46 +++++++++++++--------------------- drivers/cpufreq/cpufreq_governor.h | 3 +-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++- 4 files changed, 29 insertions(+), 33 deletions(-)
drivers/cpufreq/cpufreq_conservative.c +1 -1
@@ -242,7 +242,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall,0 );if (cs_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
drivers/cpufreq/cpufreq_governor.c +17 -29
91 lines not on this page · raw message
drivers/cpufreq/cpufreq_governor.h +1 -2
@@ -87,7 +87,6 @@ struct cpu_dbs_common_info {struct od_cpu_dbs_info_s {struct cpu_dbs_common_info cdbs; -u64 prev_cpu_iowait;struct cpufreq_frequency_table *freq_table;unsigned int freq_lo;unsigned int freq_lo_jiffies;
@@ -169,7 +168,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate)return delay; } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall); +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy);void dbs_check_cpu (struct dbs_data *dbs_data,int cpu);bool need_load_eval (struct cpu_dbs_common_info *cdbs,unsigned int sampling_rate);
drivers/cpufreq/cpufreq_ondemand.c +10 -1
@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, {unsigned int input;int ret; +unsigned int j; ret =sscanf (buf,"%u" , &input);if (ret !=1 )return -EINVAL ; od_tuners.io_is_busy = !!input; + +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info; + dbs_info = &per_cpu (od_cpu_dbs_info, j); + dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
@@ -411,7 +420,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct od_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (od_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy);if (od_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
Signature · 1 line
1.8.1.2
Quoted 9 lines · Stratos Karafotis
Currently we always calculate the CPU iowait time and add it to idle time. If we are in ondemand and we use
io_is_busy, we re-calculate iowait time and we subtract it from idle time.With this patch iowait time is calculated only when necessary avoiding the double call to
get_cpu_iowait_time_us. We use a parameter in functionget_cpu_idle_timeto distinguish when the iowait time will be added to idle time or not, without the need of keeping theprev_io_wait.
Quoted 7 lines
Signed-off-by Stratos Karafotis <[email protected]>--- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_governor.c | 46 +++++++++++++--------------------- drivers/cpufreq/cpufreq_governor.h | 3 +-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++- 4 files changed, 29 insertions(+), 33 deletions(-)
I have really spent some 10-15 minutes reviewing this patch as initially it looked to me like something is missing here and calculations are going wrong.
But it was fine :)
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, · line 344
Quoted 11 lines
drivers/cpufreq/cpufreq_ondemand.c +4
-0@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, { +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info; + dbs_info = &per_cpu (od_cpu_dbs_info, j);
Probably squash above two lines and give a blank line after it.
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, · line 357
Quoted 5 lines
drivers/cpufreq/cpufreq_ondemand.c +3
-0+ dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
And after that add my:
Hi Viresh,
Quoted 4 lines · Viresh Kumar
I have really spent some 10-15 minutes reviewing this patch as initially it looked to me like something is missing here and calculations are going wrong.
But it was fine :)
Thanks for you review.
Quoted 20 lines
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, · line 344
Quoted 11 lines
drivers/cpufreq/cpufreq_ondemand.c +4
-0@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, { +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info; + dbs_info = &per_cpu (od_cpu_dbs_info, j);Probably squash above two lines and give a blank line after it.
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, · line 349
Quoted 5 lines
drivers/cpufreq/cpufreq_ondemand.c +3
-0+ dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
Quoted 4 lines
And after that add my:
Acked-by Viresh Kumar <[email protected]>
Bellow V2 with your suggestion included.
Regards,
Stratos
----------------8<----------------------
Currently we always calculate the CPU iowait time and add it to idle time. If we are in ondemand and we use io_is_busy, we re-calculate iowait time and we subtract it from idle time.
With this patch iowait time is calculated only when necessary avoiding the double call to get_cpu_iowait_time_us. We use a parameter in function get_cpu_idle_time to distinguish when the iowait time will be added to idle time or not, without the need of keeping the prev_io_wait.
--- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_governor.c | 46 +++++++++++++--------------------- drivers/cpufreq/cpufreq_governor.h | 3 +-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++- 4 files changed, 29 insertions(+), 33 deletions(-)
drivers/cpufreq/cpufreq_conservative.c +1 -1
@@ -242,7 +242,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall,0 );if (cs_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
drivers/cpufreq/cpufreq_governor.c +17 -29
91 lines not on this page · raw message
drivers/cpufreq/cpufreq_governor.h +1 -2
@@ -87,7 +87,6 @@ struct cpu_dbs_common_info {struct od_cpu_dbs_info_s {struct cpu_dbs_common_info cdbs; -u64 prev_cpu_iowait;struct cpufreq_frequency_table *freq_table;unsigned int freq_lo;unsigned int freq_lo_jiffies;
@@ -169,7 +168,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate)return delay; } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall); +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy);void dbs_check_cpu (struct dbs_data *dbs_data,int cpu);bool need_load_eval (struct cpu_dbs_common_info *cdbs,unsigned int sampling_rate);
drivers/cpufreq/cpufreq_ondemand.c +10 -1
@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, {unsigned int input;int ret; +unsigned int j; ret =sscanf (buf,"%u" , &input);if (ret !=1 )return -EINVAL ; od_tuners.io_is_busy = !!input; + +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info = &per_cpu (od_cpu_dbs_info, + j); + dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
@@ -411,7 +420,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct od_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (od_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy);if (od_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
Signature · 1 line
1.8.1.2
Quoted 178 lines · Stratos Karafotis
Currently we always calculate the CPU iowait time and add it to idle time. If we are in ondemand and we use
io_is_busy, we re-calculate iowait time and we subtract it from idle time.With this patch iowait time is calculated only when necessary avoiding the double call to
get_cpu_iowait_time_us. We use a parameter in functionget_cpu_idle_timeto distinguish when the iowait time will be added to idle time or not, without the need of keeping theprev_io_wait.Signed-off-by Stratos Karafotis <[email protected]>--- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_governor.c | 46 +++++++++++++--------------------- drivers/cpufreq/cpufreq_governor.h | 3 +-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++- 4 files changed, 29 insertions(+), 33 deletions(-)drivers/cpufreq/cpufreq_conservative.c +1
-1@@ -242,7 +242,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall,0 );if (cs_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];drivers/cpufreq/cpufreq_governor.c +17
-29@@ -50,13 +50,13 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)return cputime_to_usecs (idle_time); } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall) +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy) {u64 idle_time =get_cpu_idle_time_us (cpu,NULL );if (idle_time ==-1ULL )return get_cpu_idle_time_jiffy (cpu, wall); -else +else if (!io_busy) idle_time +=get_cpu_iowait_time_us (cpu, wall);return idle_time;@@ -83,13 +83,22 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)/* Get Absolute Load (in terms of freq for ondemand gov) */ for_each_cpu (j, policy->cpus) {struct cpu_dbs_common_info *j_cdbs; -u64 cur_wall_time, cur_idle_time, cur_iowait_time; -unsigned int idle_time, wall_time, iowait_time; +u64 cur_wall_time, cur_idle_time; +unsigned int idle_time, wall_time;unsigned int load; +int io_busy =0 ; j_cdbs = dbs_data->get_cpu_cdbs (j); - cur_idle_time =get_cpu_idle_time (j, &cur_wall_time); +/* +* 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 do not add +* the iowait time to the cpu idle time. +*/ +if (dbs_data->governor ==GOV_ONDEMAND ) + io_busy = od_tuners->io_is_busy; + cur_idle_time =get_cpu_idle_time (j, &cur_wall_time, io_busy); wall_time = (unsigned int ) (cur_wall_time - j_cdbs->prev_cpu_wall);@@ -117,29 +126,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) idle_time +=jiffies_to_usecs (cur_nice_jiffies); } -if (dbs_data->governor ==GOV_ONDEMAND ) { -struct od_cpu_dbs_info_s *od_j_dbs_info = - dbs_data->get_cpu_dbs_info_s (cpu); - - cur_iowait_time =get_cpu_iowait_time_us (j, - &cur_wall_time); -if (cur_iowait_time ==-1ULL ) - cur_iowait_time =0 ; - - iowait_time = (unsigned int ) (cur_iowait_time - - od_j_dbs_info->prev_cpu_iowait); - od_j_dbs_info->prev_cpu_iowait = cur_iowait_time; - -/* -* 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 (od_tuners->io_is_busy && idle_time >= iowait_time) - idle_time -= iowait_time; - } -if (unlikely (!wall_time || wall_time < idle_time))continue ;@@ -207,6 +193,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data,struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;struct cpu_dbs_common_info *cpu_cdbs;unsigned int *sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; +int io_busy =0 ;int rc; cpu_cdbs = dbs_data->get_cpu_cdbs (cpu);@@ -221,6 +208,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, sampling_rate = &od_tuners->sampling_rate; ignore_nice = od_tuners->ignore_nice; od_ops = dbs_data->gov_ops; + io_busy = od_tuners->io_is_busy; }switch (event) {@@ -237,7 +225,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, j_cdbs->cpu = j; j_cdbs->cur_policy = policy; j_cdbs->prev_cpu_idle =get_cpu_idle_time (j, - &j_cdbs->prev_cpu_wall); + &j_cdbs->prev_cpu_wall, io_busy);if (ignore_nice) j_cdbs->prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];drivers/cpufreq/cpufreq_governor.h +1
-2@@ -87,7 +87,6 @@ struct cpu_dbs_common_info {struct od_cpu_dbs_info_s {struct cpu_dbs_common_info cdbs; -u64 prev_cpu_iowait;struct cpufreq_frequency_table *freq_table;unsigned int freq_lo;unsigned int freq_lo_jiffies;@@ -169,7 +168,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate)return delay; } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall); +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy);void dbs_check_cpu (struct dbs_data *dbs_data,int cpu);bool need_load_eval (struct cpu_dbs_common_info *cdbs,unsigned int sampling_rate);drivers/cpufreq/cpufreq_ondemand.c +9
-0@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, {unsigned int input;int ret; +unsigned int j; ret =sscanf (buf,"%u" , &input);if (ret !=1 )return -EINVAL ; od_tuners.io_is_busy = !!input; + +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info = &per_cpu (od_cpu_dbs_info, + j); + dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, · line 426
Quoted 8 lines
drivers/cpufreq/cpufreq_ondemand.c +1
-1@@ -411,7 +420,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct od_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (od_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy);if (od_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
Rafael J. Wysocki
AppliedQuoted 178 lines · Viresh Kumar
Quoted 177 lines · Stratos Karafotis
Currently we always calculate the CPU iowait time and add it to idle time. If we are in ondemand and we use
io_is_busy, we re-calculate iowait time and we subtract it from idle time.With this patch iowait time is calculated only when necessary avoiding the double call to
get_cpu_iowait_time_us. We use a parameter in functionget_cpu_idle_timeto distinguish when the iowait time will be added to idle time or not, without the need of keeping theprev_io_wait.Signed-off-by Stratos Karafotis <[email protected]>--- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_governor.c | 46 +++++++++++++--------------------- drivers/cpufreq/cpufreq_governor.h | 3 +-- drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++- 4 files changed, 29 insertions(+), 33 deletions(-)drivers/cpufreq/cpufreq_conservative.c +1
-1@@ -242,7 +242,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (cs_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall,0 );if (cs_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];drivers/cpufreq/cpufreq_governor.c +17
-29@@ -50,13 +50,13 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)return cputime_to_usecs (idle_time); } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall) +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy) {u64 idle_time =get_cpu_idle_time_us (cpu,NULL );if (idle_time ==-1ULL )return get_cpu_idle_time_jiffy (cpu, wall); -else +else if (!io_busy) idle_time +=get_cpu_iowait_time_us (cpu, wall);return idle_time;@@ -83,13 +83,22 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)/* Get Absolute Load (in terms of freq for ondemand gov) */ for_each_cpu (j, policy->cpus) {struct cpu_dbs_common_info *j_cdbs; -u64 cur_wall_time, cur_idle_time, cur_iowait_time; -unsigned int idle_time, wall_time, iowait_time; +u64 cur_wall_time, cur_idle_time; +unsigned int idle_time, wall_time;unsigned int load; +int io_busy =0 ; j_cdbs = dbs_data->get_cpu_cdbs (j); - cur_idle_time =get_cpu_idle_time (j, &cur_wall_time); +/* +* 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 do not add +* the iowait time to the cpu idle time. +*/ +if (dbs_data->governor ==GOV_ONDEMAND ) + io_busy = od_tuners->io_is_busy; + cur_idle_time =get_cpu_idle_time (j, &cur_wall_time, io_busy); wall_time = (unsigned int ) (cur_wall_time - j_cdbs->prev_cpu_wall);@@ -117,29 +126,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) idle_time +=jiffies_to_usecs (cur_nice_jiffies); } -if (dbs_data->governor ==GOV_ONDEMAND ) { -struct od_cpu_dbs_info_s *od_j_dbs_info = - dbs_data->get_cpu_dbs_info_s (cpu); - - cur_iowait_time =get_cpu_iowait_time_us (j, - &cur_wall_time); -if (cur_iowait_time ==-1ULL ) - cur_iowait_time =0 ; - - iowait_time = (unsigned int ) (cur_iowait_time - - od_j_dbs_info->prev_cpu_iowait); - od_j_dbs_info->prev_cpu_iowait = cur_iowait_time; - -/* -* 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 (od_tuners->io_is_busy && idle_time >= iowait_time) - idle_time -= iowait_time; - } -if (unlikely (!wall_time || wall_time < idle_time))continue ;@@ -207,6 +193,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data,struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;struct cpu_dbs_common_info *cpu_cdbs;unsigned int *sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; +int io_busy =0 ;int rc; cpu_cdbs = dbs_data->get_cpu_cdbs (cpu);@@ -221,6 +208,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, sampling_rate = &od_tuners->sampling_rate; ignore_nice = od_tuners->ignore_nice; od_ops = dbs_data->gov_ops; + io_busy = od_tuners->io_is_busy; }switch (event) {@@ -237,7 +225,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, j_cdbs->cpu = j; j_cdbs->cur_policy = policy; j_cdbs->prev_cpu_idle =get_cpu_idle_time (j, - &j_cdbs->prev_cpu_wall); + &j_cdbs->prev_cpu_wall, io_busy);if (ignore_nice) j_cdbs->prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];drivers/cpufreq/cpufreq_governor.h +1
-2@@ -87,7 +87,6 @@ struct cpu_dbs_common_info {struct od_cpu_dbs_info_s {struct cpu_dbs_common_info cdbs; -u64 prev_cpu_iowait;struct cpufreq_frequency_table *freq_table;unsigned int freq_lo;unsigned int freq_lo_jiffies;@@ -169,7 +168,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate)return delay; } -u64 get_cpu_idle_time (unsigned int cpu,u64 *wall); +u64 get_cpu_idle_time (unsigned int cpu,u64 *wall,int io_busy);void dbs_check_cpu (struct dbs_data *dbs_data,int cpu);bool need_load_eval (struct cpu_dbs_common_info *cdbs,unsigned int sampling_rate);drivers/cpufreq/cpufreq_ondemand.c +9
-0@@ -339,11 +339,20 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, {unsigned int input;int ret; +unsigned int j; ret =sscanf (buf,"%u" , &input);if (ret !=1 )return -EINVAL ; od_tuners.io_is_busy = !!input; + +/* we need to re-evaluate prev_cpu_idle */ +for_each_online_cpu (j) { +struct od_cpu_dbs_info_s *dbs_info = &per_cpu (od_cpu_dbs_info, + j); + dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy); + }return count; }
Quoted 11 lines
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, · line 426
Quoted 9 lines
drivers/cpufreq/cpufreq_ondemand.c +1
-1@@ -411,7 +420,7 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,struct od_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu (od_cpu_dbs_info, j); dbs_info->cdbs.prev_cpu_idle =get_cpu_idle_time (j, - &dbs_info->cdbs.prev_cpu_wall); + &dbs_info->cdbs.prev_cpu_wall, od_tuners.io_is_busy);if (od_tuners.ignore_nice) dbs_info->cdbs.prev_cpu_nice =kcpustat_cpu (j).cpustat[CPUTIME_NICE ];
Applied to linux-pm.git/bleeding-edge and will be moved to linux-next if there are no build problems in the bleeding-edge branch.
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 6 lines · Rafael J. Wysocki
Applied to linux-pm.git/bleeding-edge and will be moved to linux-next if there are no build problems in the bleeding-edge branch.
Thanks,
Rafael
Hi Rafael,
I just noticed a regression with this patch with the calculation of wall time in get get_cpu_idle_time that prevents the CPU to increase to max frequency, when we use ondemand with io_is_busy = 1.
I'm sorry about that, I'm sending a patch to fix it.
Regards,
Stratos