cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
PATCH 1/1 cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
Instead of checking only the absolute value of CPU load_freq to increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.
Every sampling rate, we calculate the gradient of load_freq. If it is too steep we assume that the load most probably will go over up_threshold in next iteration(s). We reduce up_threshold by early_differential to achieve frequency increase in the current iteration.
A new tuner early_demand is introduced to enable this functionality (disabled by default). Also we use new tuners to control early demand:
- early_differential: controls the final up_threshold
- grad_up_threshold: over this gradient of load we will decrease up_threshold by early_differential.
--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 4 ++++ drivers/cpufreq/cpufreq_ondemand.c | 41 +++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +1 -0
@@ -276,6 +276,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu);if (!policy->governor->initialized)
drivers/cpufreq/cpufreq_governor.h +4 -0
@@ -94,6 +94,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {
@@ -112,6 +113,9 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int early_differential; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {
drivers/cpufreq/cpufreq_ondemand.c +40 -1
89 lines not on this page · raw message
Signature · 1 line
1.8.1.2
Viresh Kumar
maintainerHi Stratos,
Quoted 10 lines · Stratos Karafotis
Instead of checking only the absolute value of CPU
load_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s). We reduceup_thresholdbyearly_differentialto achieve frequency increase in the current iteration.
Quoted 8 lines
A new tuner
early_demandis introduced to enable this functionality (disabled by default). Also we use new tuners to control early demand:-
early_differential: controls the finalup_threshold
-grad_up_threshold: over this gradient of load we will decreaseup_thresholdbyearly_differential.Signed-off-by Stratos Karafotis <[email protected]>
Sorry for this but i already have a patchset which has changed these files to some extent. Can you please rebase over them? Actually my patchset is already accepted, its just that rafael didn't wanted to have them for 3.9.
http://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/cpufreq-for-3.10
Back to your patch:
Following is what i understood about this patch:
- The only case where this code will come into picture is when load is below up_threshold.
- And we see a steep rise in the load from previous request..
i.e. (with the default values)
UP_THRESHOLD (80)GRAD_UP_THESHOLD (50)EARLY_DIFFERENTIAL (45)
If the load was 10 previously and it went to 80 > load >= 60, we will make up_threshold as 80-45 = 35. Which is lower than grad_up_threshold :)
Isn't it strange?
So, probably you just don't need this tunable: early_differential. Rather just increase the frequency without doing this calculation:
if (load_freq > od_tuners.up_threshold * policy->cur) {
drivers/cpufreq/cpufreq_ondemand.c line 33
Quoted 9 lines
drivers/cpufreq/cpufreq_ondemand.c +1
-0@@ -30,6 +30,8 @@#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10)#define DEF_FREQUENCY_UP_THRESHOLD (80)#define DEF_SAMPLING_DOWN_FACTOR (1) +#define DEF_GRAD_UP_THESHOLD (50)
s/THESHOLD/THRESHOLD
Quoted 7 lines
drivers/cpufreq/cpufreq_ondemand.c +2
-0@@ -170,11 +175,29 @@ static void od_check_cpu(int cpu, unsigned int load_freq) {struct od_cpu_dbs_info_s *dbs_info = &per_cpu (od_cpu_dbs_info, cpu);struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; +unsigned int up_threshold = od_tuners.up_threshold; +unsigned int grad;
drivers/cpufreq/cpufreq_ondemand.c static void od_check_cpu(int cpu, unsigned int load_freq) · line 190
Quoted 10 lines
drivers/cpufreq/cpufreq_ondemand.c +8
-0dbs_info->freq_lo =0 ; +/* +* Calculate the gradient of load_freq. If it is too steep we assume +* that the load will go over up_threshold in next iteration(s). We +* reduce up_threshold by early_differential to achieve frequency +* increase earlier +*/ +if (od_tuners.early_demand) { +if (load_freq > dbs_info->prev_load_freq) {
&& (load_freq < od_tuners.up_threshold * policy->cur) ??
Quoted 15 lines
drivers/cpufreq/cpufreq_ondemand.c +9
-1+ grad = load_freq - dbs_info->prev_load_freq; + +if (grad > od_tuners.grad_up_threshold * policy->cur) + up_threshold -= od_tuners.early_differential; + } + dbs_info->prev_load_freq = load_freq; + } +/* Check for frequency increase */ -if (load_freq > od_tuners.up_threshold * policy->cur) { +if (load_freq > up_threshold * policy->cur) {/* If switching to max speed, apply sampling_down_factor */ if (policy->cur < policy->max) dbs_info->rate_mult =
drivers/cpufreq/cpufreq_ondemand.c static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b, · line 464
Quoted 4 lines
drivers/cpufreq/cpufreq_ondemand.c +1
-0@@ -438,12 +461,26 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,return count; } +show_one (od, early_demand, early_demand);
What about making other two tunables rw?
Hi Viresh,
Thank you very much for your review and your suggestions.
Quoted 5 lines · Viresh Kumar
Sorry for this but i already have a patchset which has changed these files to some extent. Can you please rebase over them? Actually my patchset is already accepted, its just that rafael didn't wanted to have them for 3.9.
http://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/cpufreq-for-3.10
No problem. I rebased the patch over your tree.
Quoted 4 lines
So, probably you just don't need this tunable:
early_differential. Rather just increase the frequency without doing this calculation:if (
load_freq> od_tuners.up_threshold *policy->cur) {
I agree with your suggestion. This is simpler approach. So, if the gradient is greater than grad_up_threshold we increase frequency immediately. i.e.
if previous load was 10 and current load is 65 the gradient will be 55 (> grad_up_theshold) and we increase frequency
Quoted 4 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (od_tuners.early_demand) { + if (load_freq > dbs_info->prev_load_freq) {&& (
load_freq< od_tuners.up_threshold *policy->cur) ??
In my opinion this is not necessary. If load_freq is greater, then we have to increase frequency in anyway.
Quoted 5 lines
Quoted 2 lines
+show_one(od,
early_demand,early_demand);What about making other two tunables rw?
Of course. I added the grad_up_threshold.
Following patch v2.
Thanks again,
Stratos
------------------------8<---------------------------------------------- Instead of checking only the absolute value of CPU load_freq to increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.
Every sampling rate, we calculate the gradient of load_freq. If it is too steep we assume that the load most probably will go over up_threshold in next iteration(s) and we increase frequency immediately.
New tuners are introduced:
- early_demand: to enable this functionality (disabled by default).
- grad_up_threshold: over this gradient of load we will increase frequency immediately.
--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 6 +++- drivers/cpufreq/cpufreq_ondemand.c | 72 ++++++++++++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 7 deletions(-)
drivers/cpufreq/cpufreq_governor.c +1 -0
@@ -322,6 +322,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu); }
drivers/cpufreq/cpufreq_governor.h +5 -1
@@ -96,6 +96,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {
@@ -114,6 +115,8 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {
@@ -160,7 +163,8 @@ struct od_ops {void (*powersave_bias_init_cpu)(int cpu);unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,unsigned int freq_next,unsigned int relation); -void (*freq_increase)(struct cpufreq_policy *p,unsigned int freq); +void (*freq_increase)(struct od_cpu_dbs_info_s *dbs_info, +struct cpufreq_policy *p,unsigned int freq); };struct cs_ops {
drivers/cpufreq/cpufreq_ondemand.c +66 -6
132 lines not on this page · raw message
Signature · 1 line
1.8.1.2
Viresh Kumar
maintainerHi Again,
Quoted 25 lines · Stratos Karafotis
drivers/cpufreq/cpufreq_ondemand.c +17
-0@@ -168,16 +174,29 @@ static void od_check_cpu(int cpu, unsigned int load_freq)struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;struct dbs_data *dbs_data = policy->governor_data;struct od_dbs_tuners *od_tuners = dbs_data->tuners; +unsigned int prev_load_freq; dbs_info->freq_lo =0 ; +/* +* Calculate the gradient of load_freq. If it is too steep we assume +* that the load will go over up_threshold in next iteration(s) and +* we increase the frequency immediately +*/ +if (od_tuners->early_demand) { + prev_load_freq = dbs_info->prev_load_freq; + dbs_info->prev_load_freq = load_freq; + +if (load_freq > prev_load_freq && (load_freq - prev_load_freq > + od_tuners->grad_up_threshold * policy->cur)) { +dbs_freq_increase (dbs_info, policy, policy->max); +return ; + } + } +
drivers/cpufreq/cpufreq_ondemand.c static void od_check_cpu(int cpu, unsigned int load_freq) · line 201
Quoted 10 lines
drivers/cpufreq/cpufreq_ondemand.c +1
-5/* Check for frequency increase */ if (load_freq > od_tuners->up_threshold * policy->cur) { -/* If switching to max speed, apply sampling_down_factor */ -if (policy->cur < policy->max) - dbs_info->rate_mult = - od_tuners->sampling_down_factor; -dbs_freq_increase (policy, policy->max); +dbs_freq_increase (dbs_info, policy, policy->max);return ; }
Not really against your implementation, but this is what i thought of how it should look like (initially when i reviewed your V1)
int boost_freq = 0;
if (od_tuners->early_demand) {
if (load_freq > dbs_info->prev_load_freq && (load_freq
- dbs_info->prev_load_freq >
od_tuners->grad_up_threshold * policy->cur)) {
boost_freq = 1;
}
dbs_info->prev_load_freq = load_freq;
}
/* Check for frequency increase */
if (boost_freq || (load_freq > od_tuners->up_threshold * policy->cur)) {
increase-freq;This would get rid of duplicate calls to increase_freq() and also avoid changing its
prototype.
Hi,
Quoted 19 lines · Viresh Kumar
Hi Again,
int
boost_freq= 0;if (od_tuners->early_demand) { if (load_freq > dbs_info->prev_load_freq && (load_freq - dbs_info->prev_load_freq > od_tuners->grad_up_threshold * policy->cur)) { boost_freq = 1; } dbs_info->prev_load_freq = load_freq; } /* Check for frequency increase */ if (boost_freq || (load_freq > od_tuners->up_threshold * policy->cur)) { increase-freq;
Quoted 4 lines
This would get rid of duplicate calls to
increase_freq()and also avoid changing its
prototype.
Thanks again. Following V3 with your suggestion.
Regards,
Stratos
-----------------------8<-------------------------------------------- Instead of checking only the absolute value of CPU load_freq to increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.
Every sampling rate, we calculate the gradient of load_freq. If it is too steep we assume that the load most probably will go over up_threshold in next iteration(s) and we increase frequency immediately.
New tuners are introduced:
- early_demand: to enable this functionality (disabled by default).
- grad_up_threshold: over this gradient of load we will increase frequency immediately.
--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 3 ++ drivers/cpufreq/cpufreq_ondemand.c | 59 +++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +1 -0
@@ -322,6 +322,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu); }
drivers/cpufreq/cpufreq_governor.h +3 -0
@@ -96,6 +96,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {
@@ -114,6 +115,8 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {
drivers/cpufreq/cpufreq_ondemand.c +58 -1
108 lines not on this page · raw message
Signature · 1 line
1.8.1.2
Quoted 14 lines · Stratos Karafotis
Thanks again. Following V3 with your suggestion.
Regards,
Stratos-----------------------8<-------------------------------------------- Instead of checking only the absolute value of CPU
load_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s) and we increase frequency immediately.
Quoted 6 lines
New tuners are introduced:
-early_demand: to enable this functionality (disabled by default).
-grad_up_threshold: over this gradient of load we will increase frequency immediately.Signed-off-by Stratos Karafotis <[email protected]>
Viresh Kumar
maintainerQuoted 10 lines · Viresh Kumar
Quoted 8 lines · Stratos Karafotis
Instead of checking only the absolute value of CPU
load_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s) and we increase frequency immediately.
Quoted 8 lines
Quoted 6 lines
New tuners are introduced:
-early_demand: to enable this functionality (disabled by default).
-grad_up_threshold: over this gradient of load we will increase frequency immediately.Signed-off-by Stratos Karafotis <[email protected]>Acked-by Viresh Kumar <[email protected]>
Rafael,
I applied it here with my Ack over my patches, for getting a run by "kbuild test robot".
http://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/cpufreq-for-3.10
Quoted 18 lines · Viresh Kumar
Quoted 17 lines · Viresh Kumar
Quoted 14 lines · Stratos Karafotis
Instead of checking only the absolute value of CPU
load_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s) and we increase frequency immediately.New tuners are introduced:
-early_demand: to enable this functionality (disabled by default).
-grad_up_threshold: over this gradient of load we will increase frequency immediately.Signed-off-by Stratos Karafotis <[email protected]>
Quoted 8 lines
Quoted 1 line
Acked-by Viresh Kumar <[email protected]>Rafael,
I applied it here with my Ack over my patches, for getting a run by "kbuild test robot".
http://git.linaro.org/gitweb?p=people/vireshk/linux.git;a=shortlog;h=refs/heads/cpufreq-for-3.10
Thanks, but I'm still not entirely sure about the have_multiple_policies stuff (yes, I saw your arguments) and the v3.10 merge window is still two months away. IOW, please slow down a bit.
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 6 lines · Viresh Kumar
Quoted 1 line · Stratos Karafotis
Signed-off-by Stratos Karafotis <[email protected]>Acked-by Viresh Kumar <[email protected]>
Hi Rafael,
In case you are interested in this patch I rebased it to the latest linux-pm/bleeding-edge.
Thanks,
Stratos
------------------------------------------
Instead of checking only the absolute value of CPU load_freq to increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.
Every sampling rate, we calculate the gradient of load_freq. If it is too steep we assume that the load most probably will go over up_threshold in next iteration(s) and we increase frequency immediately.
New tuners are introduced:
- early_demand: to enable this functionality (disabled by default).
- grad_up_threshold: over this gradient of load we will increase frequency immediately.
--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 3 ++ drivers/cpufreq/cpufreq_ondemand.c | 59 +++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +1 -0
@@ -328,6 +328,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu); }
drivers/cpufreq/cpufreq_governor.h +3 -0
@@ -95,6 +95,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {
@@ -113,6 +114,8 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {
drivers/cpufreq/cpufreq_ondemand.c +58 -1
108 lines not on this page · raw message
Signature · 1 line
1.8.1.4
Quoted 11 lines · Stratos Karafotis
Quoted 6 lines · Viresh Kumar
Quoted 1 line · Stratos Karafotis
Signed-off-by Stratos Karafotis <[email protected]>Acked-by Viresh Kumar <[email protected]>Hi Rafael,
In case you are interested in this patch I rebased it to the latest linux-pm/bleeding-edge.
Thanks!
I have a backlog of cpufreq patches to sort out, so it may take some time till I get to this one.
Thanks,
Rafael
Quoted 173 lines
------------------------------------------
Instead of checking only the absolute value of CPUload_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s) and we increase frequency immediately.New tuners are introduced:
-early_demand: to enable this functionality (disabled by default).
-grad_up_threshold: over this gradient of load we will increase frequency immediately.Signed-off-by Stratos Karafotis <[email protected]>--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 3 ++ drivers/cpufreq/cpufreq_ondemand.c | 59 +++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-)drivers/cpufreq/cpufreq_governor.c +1
-0@@ -328,6 +328,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu); }drivers/cpufreq/cpufreq_governor.h +3
-0@@ -95,6 +95,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {@@ -113,6 +114,8 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {drivers/cpufreq/cpufreq_ondemand.c +58
-1@@ -31,6 +31,7 @@#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10)#define DEF_FREQUENCY_UP_THRESHOLD (80)#define DEF_SAMPLING_DOWN_FACTOR (1) +#define DEF_GRAD_UP_THRESHOLD (50)#define MAX_SAMPLING_DOWN_FACTOR (100000)#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3)#define MICRO_FREQUENCY_UP_THRESHOLD (95)@@ -168,11 +169,26 @@ static void od_check_cpu(int cpu, unsigned int load_freq)struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;struct dbs_data *dbs_data = policy->governor_data;struct od_dbs_tuners *od_tuners = dbs_data->tuners; +int boost_freq =0 ; dbs_info->freq_lo =0 ; +/* +* Calculate the gradient of load_freq. If it is too steep we assume +* that the load will go over up_threshold in next iteration(s) and +* we increase the frequency immediately +*/ +if (od_tuners->early_demand) { +if (load_freq > dbs_info->prev_load_freq && + (load_freq - dbs_info->prev_load_freq > + od_tuners->grad_up_threshold * policy->cur)) + boost_freq =1 ; + + dbs_info->prev_load_freq = load_freq; + } +/* Check for frequency increase */ -if (load_freq > od_tuners->up_threshold * policy->cur) { +if (boost_freq || load_freq > od_tuners->up_threshold * policy->cur) {/* If switching to max speed, apply sampling_down_factor */ if (policy->cur < policy->max) dbs_info->rate_mult =@@ -454,12 +470,47 @@ static ssize_t store_powersave_bias(struct cpufreq_policy *policy,return count; } +static ssize_t store_grad_up_threshold (struct cpufreq_policy *policy, +const char *buf,size_t count) +{ +struct dbs_data *dbs_data = policy->governor_data; +struct od_dbs_tuners *od_tuners = dbs_data->tuners; +unsigned int input; +int ret; + ret =sscanf (buf,"%u" , &input); + +if (ret !=1 || input >MAX_FREQUENCY_UP_THRESHOLD || + input <MIN_FREQUENCY_UP_THRESHOLD ) { +return -EINVAL ; + } + + od_tuners->grad_up_threshold = input; +return count; +} + +static ssize_t store_early_demand (struct cpufreq_policy *policy, +const char *buf,size_t count) +{ +struct dbs_data *dbs_data = policy->governor_data; +struct od_dbs_tuners *od_tuners = dbs_data->tuners; +unsigned int input; +int ret; + + ret =sscanf (buf,"%u" , &input); +if (ret !=1 ) +return -EINVAL ; + od_tuners->early_demand = !!input; +return count; +} +show_one (od, sampling_rate, sampling_rate);show_one (od, io_is_busy, io_is_busy);show_one (od, up_threshold, up_threshold);show_one (od, sampling_down_factor, sampling_down_factor);show_one (od, ignore_nice, ignore_nice);show_one (od, powersave_bias, powersave_bias); +show_one (od, grad_up_threshold, grad_up_threshold); +show_one (od, early_demand, early_demand);declare_show_sampling_rate_min ();cpufreq_freq_attr_rw (sampling_rate);@@ -468,6 +519,8 @@ cpufreq_freq_attr_rw(up_threshold);cpufreq_freq_attr_rw (sampling_down_factor);cpufreq_freq_attr_rw (ignore_nice);cpufreq_freq_attr_rw (powersave_bias); +cpufreq_freq_attr_rw (grad_up_threshold); +cpufreq_freq_attr_rw (early_demand);cpufreq_freq_attr_ro (sampling_rate_min);static struct attribute *dbs_attributes[] = {@@ -478,6 +531,8 @@ static struct attribute *dbs_attributes[] = { &ignore_nice.attr, &powersave_bias.attr, &io_is_busy.attr, + &grad_up_threshold.attr, + &early_demand.attr, NULL };@@ -525,9 +580,11 @@ static int od_init(struct dbs_data *dbs_data) } tuners->sampling_down_factor =DEF_SAMPLING_DOWN_FACTOR ; + tuners->grad_up_threshold =DEF_GRAD_UP_THRESHOLD ; tuners->ignore_nice =0 ; tuners->powersave_bias =0 ; tuners->io_is_busy =should_io_be_busy (); + tuners->early_demand =0 ; dbs_data->tuners = tuners;mutex_init (&dbs_data->mutex);
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 20 lines · Stratos Karafotis
Quoted 6 lines · Viresh Kumar
Quoted 1 line · Stratos Karafotis
Signed-off-by Stratos Karafotis <[email protected]>Acked-by Viresh Kumar <[email protected]>Hi Rafael,
In case you are interested in this patch I rebased it to the latest linux-pm/bleeding-edge.
Thanks,
Stratos------------------------------------------
Instead of checking only the absolute value of CPUload_freqto increase frequency, we detect forthcoming CPU load rise and increase frequency earlier.
Quoted 8 lines
Every sampling rate, we calculate the gradient of
load_freq. If it is too steep we assume that the load most probably will go overup_thresholdin next iteration(s) and we increase frequency immediately.New tuners are introduced:
-early_demand: to enable this functionality (disabled by default).
-grad_up_threshold: over this gradient of load we will increase frequency immediately.
Do you have any numbers indicating that this actually makes things better?
Rafael
Quoted 159 lines
Signed-off-by Stratos Karafotis <[email protected]>--- drivers/cpufreq/cpufreq_governor.c | 1 + drivers/cpufreq/cpufreq_governor.h | 3 ++ drivers/cpufreq/cpufreq_ondemand.c | 59 +++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-)drivers/cpufreq/cpufreq_governor.c +1
-0@@ -328,6 +328,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy, }else { od_dbs_info->rate_mult =1 ; od_dbs_info->sample_type =OD_NORMAL_SAMPLE ; + od_dbs_info->prev_load_freq =0 ; od_ops->powersave_bias_init_cpu (cpu); }drivers/cpufreq/cpufreq_governor.h +3
-0@@ -95,6 +95,7 @@ struct od_cpu_dbs_info_s {unsigned int freq_hi_jiffies;unsigned int rate_mult; unsigned int sample_type:1; +unsigned int prev_load_freq; };struct cs_cpu_dbs_info_s {@@ -113,6 +114,8 @@ struct od_dbs_tuners {unsigned int adj_up_threshold;unsigned int powersave_bias;unsigned int io_is_busy; +unsigned int grad_up_threshold; +unsigned int early_demand; };struct cs_dbs_tuners {drivers/cpufreq/cpufreq_ondemand.c +58
-1@@ -31,6 +31,7 @@#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10)#define DEF_FREQUENCY_UP_THRESHOLD (80)#define DEF_SAMPLING_DOWN_FACTOR (1) +#define DEF_GRAD_UP_THRESHOLD (50)#define MAX_SAMPLING_DOWN_FACTOR (100000)#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3)#define MICRO_FREQUENCY_UP_THRESHOLD (95)@@ -168,11 +169,26 @@ static void od_check_cpu(int cpu, unsigned int load_freq)struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;struct dbs_data *dbs_data = policy->governor_data;struct od_dbs_tuners *od_tuners = dbs_data->tuners; +int boost_freq =0 ; dbs_info->freq_lo =0 ; +/* +* Calculate the gradient of load_freq. If it is too steep we assume +* that the load will go over up_threshold in next iteration(s) and +* we increase the frequency immediately +*/ +if (od_tuners->early_demand) { +if (load_freq > dbs_info->prev_load_freq && + (load_freq - dbs_info->prev_load_freq > + od_tuners->grad_up_threshold * policy->cur)) + boost_freq =1 ; + + dbs_info->prev_load_freq = load_freq; + } +/* Check for frequency increase */ -if (load_freq > od_tuners->up_threshold * policy->cur) { +if (boost_freq || load_freq > od_tuners->up_threshold * policy->cur) {/* If switching to max speed, apply sampling_down_factor */ if (policy->cur < policy->max) dbs_info->rate_mult =@@ -454,12 +470,47 @@ static ssize_t store_powersave_bias(struct cpufreq_policy *policy,return count; } +static ssize_t store_grad_up_threshold (struct cpufreq_policy *policy, +const char *buf,size_t count) +{ +struct dbs_data *dbs_data = policy->governor_data; +struct od_dbs_tuners *od_tuners = dbs_data->tuners; +unsigned int input; +int ret; + ret =sscanf (buf,"%u" , &input); + +if (ret !=1 || input >MAX_FREQUENCY_UP_THRESHOLD || + input <MIN_FREQUENCY_UP_THRESHOLD ) { +return -EINVAL ; + } + + od_tuners->grad_up_threshold = input; +return count; +} + +static ssize_t store_early_demand (struct cpufreq_policy *policy, +const char *buf,size_t count) +{ +struct dbs_data *dbs_data = policy->governor_data; +struct od_dbs_tuners *od_tuners = dbs_data->tuners; +unsigned int input; +int ret; + + ret =sscanf (buf,"%u" , &input); +if (ret !=1 ) +return -EINVAL ; + od_tuners->early_demand = !!input; +return count; +} +show_one (od, sampling_rate, sampling_rate);show_one (od, io_is_busy, io_is_busy);show_one (od, up_threshold, up_threshold);show_one (od, sampling_down_factor, sampling_down_factor);show_one (od, ignore_nice, ignore_nice);show_one (od, powersave_bias, powersave_bias); +show_one (od, grad_up_threshold, grad_up_threshold); +show_one (od, early_demand, early_demand);declare_show_sampling_rate_min ();cpufreq_freq_attr_rw (sampling_rate);@@ -468,6 +519,8 @@ cpufreq_freq_attr_rw(up_threshold);cpufreq_freq_attr_rw (sampling_down_factor);cpufreq_freq_attr_rw (ignore_nice);cpufreq_freq_attr_rw (powersave_bias); +cpufreq_freq_attr_rw (grad_up_threshold); +cpufreq_freq_attr_rw (early_demand);cpufreq_freq_attr_ro (sampling_rate_min);static struct attribute *dbs_attributes[] = {@@ -478,6 +531,8 @@ static struct attribute *dbs_attributes[] = { &ignore_nice.attr, &powersave_bias.attr, &io_is_busy.attr, + &grad_up_threshold.attr, + &early_demand.attr, NULL };@@ -525,9 +580,11 @@ static int od_init(struct dbs_data *dbs_data) } tuners->sampling_down_factor =DEF_SAMPLING_DOWN_FACTOR ; + tuners->grad_up_threshold =DEF_GRAD_UP_THRESHOLD ; tuners->ignore_nice =0 ; tuners->powersave_bias =0 ; tuners->io_is_busy =should_io_be_busy (); + tuners->early_demand =0 ; dbs_data->tuners = tuners;mutex_init (&dbs_data->mutex);
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 3 lines · Rafael J. Wysocki
Do you have any numbers indicating that this actually makes things better?
Rafael
No, I don't.
The expected behaviour after this patch is to "force" max frequency few sampling periods earlier. The idea was to increase system responsiveness especially on 'small' embedded systems (phones for example).
Actually, I thought to provide some numbers but I had no idea how to measure this.
Would it be enough to provide the number of times that the CPU increases frequency because of early_demand versus the total number of increments?
Thanks,
Stratos
Quoted 5 lines · Stratos Karafotis
Quoted 3 lines · Rafael J. Wysocki
Do you have any numbers indicating that this actually makes things better?
Rafael
Quoted 8 lines
No, I don't.
The expected behaviour after this patch is to "force" max frequency few sampling periods earlier. The idea was to increase system responsiveness especially on 'small' embedded systems (phones for example).Actually, I thought to provide some numbers but I had no idea how to measure this.
Would it be enough to provide the number of times that the CPU increases frequency because of
early_demandversus the total number of increments?
I think it would be better to check if your approach leads to a better behavior as far as energy savings are concerned. If it actually is worse, then I don't see a reason to apply it.
Thanks,
Rafael
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.