linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
@ 2013-02-20 20:50 Stratos Karafotis
  2013-02-21  4:59 ` Viresh Kumar
  0 siblings, 1 reply; 13+ messages in thread
From: Stratos Karafotis @ 2013-02-20 20:50 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: cpufreq, linux-pm, linux-kernel

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.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 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(-)

diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 5a76086..348cb80 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -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)
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index d2ac911..d1425a7 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -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 {
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index f3eb26c..458806f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -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)
+#define DEF_EARLY_DIFFERENTIAL			(45)
 #define MAX_SAMPLING_DOWN_FACTOR		(100000)
 #define MICRO_FREQUENCY_DOWN_DIFFERENTIAL	(3)
 #define MICRO_FREQUENCY_UP_THRESHOLD		(95)
@@ -49,8 +51,11 @@ static struct od_dbs_tuners od_tuners = {
 	.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
 	.adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
 			    DEF_FREQUENCY_DOWN_DIFFERENTIAL,
+	.early_differential = DEF_EARLY_DIFFERENTIAL,
+	.grad_up_threshold = DEF_GRAD_UP_THESHOLD,
 	.ignore_nice = 0,
 	.powersave_bias = 0,
+	.early_demand = 0,
 };
 
 static void ondemand_powersave_bias_init_cpu(int cpu)
@@ -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;
 
 	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). 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) {
+			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 =
@@ -438,12 +461,26 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
 	return count;
 }
 
+static ssize_t store_early_demand(struct kobject *a, struct attribute *b,
+				  const char *buf, size_t count)
+{
+	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_load, ignore_nice);
 show_one(od, powersave_bias, powersave_bias);
+show_one(od, early_demand, early_demand);
 
 define_one_global_rw(sampling_rate);
 define_one_global_rw(io_is_busy);
@@ -452,6 +489,7 @@ define_one_global_rw(sampling_down_factor);
 define_one_global_rw(ignore_nice_load);
 define_one_global_rw(powersave_bias);
 define_one_global_ro(sampling_rate_min);
+define_one_global_rw(early_demand);
 
 static struct attribute *dbs_attributes[] = {
 	&sampling_rate_min.attr,
@@ -461,6 +499,7 @@ static struct attribute *dbs_attributes[] = {
 	&ignore_nice_load.attr,
 	&powersave_bias.attr,
 	&io_is_busy.attr,
+	&early_demand.attr,
 	NULL
 };
 
-- 
1.8.1.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-20 20:50 [PATCH linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency Stratos Karafotis
@ 2013-02-21  4:59 ` Viresh Kumar
  2013-02-21 11:31   ` [PATCH v2 " Stratos Karafotis
  0 siblings, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2013-02-21  4:59 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Rafael J. Wysocki, cpufreq, linux-pm, linux-kernel

Hi Stratos,

On Thu, Feb 21, 2013 at 2:20 AM, Stratos Karafotis
<stratosk@semaphore.gr> wrote:
> 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.
>
> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>

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) {

> diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> index f3eb26c..458806f 100644
> --- a/drivers/cpufreq/cpufreq_ondemand.c
> +++ b/drivers/cpufreq/cpufreq_ondemand.c
> @@ -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

> @@ -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;
>
>         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). 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) ??

> +                       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 =
> @@ -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?

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-21  4:59 ` Viresh Kumar
@ 2013-02-21 11:31   ` Stratos Karafotis
  2013-02-21 15:33     ` Viresh Kumar
  0 siblings, 1 reply; 13+ messages in thread
From: Stratos Karafotis @ 2013-02-21 11:31 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: Rafael J. Wysocki, cpufreq, linux-pm, linux-kernel

Hi Viresh,

Thank you very much for your review and your suggestions.

On 02/21/2013 06:59 AM, Viresh Kumar wrote:
> 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.

> 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

>> +       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.

> 
>> +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.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 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(-)

diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 7722505..e737aa9 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -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);
 		}
 
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 6301790..c9a237a 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -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 {
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index c5fd794..4c948af 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -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)
@@ -139,11 +140,16 @@ static void ondemand_powersave_bias_init(void)
 	}
 }
 
-static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+static void dbs_freq_increase(struct od_cpu_dbs_info_s *dbs_info,
+			      struct cpufreq_policy *p, unsigned int freq)
 {
 	struct dbs_data *dbs_data = p->governor_data;
 	struct od_dbs_tuners *od_tuners = dbs_data->tuners;
 
+	/* If switching to max speed, apply sampling_down_factor */
+	if (p->cur < p->max)
+		dbs_info->rate_mult = od_tuners->sampling_down_factor;
+
 	if (od_tuners->powersave_bias)
 		freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
 	else if (p->cur == p->max)
@@ -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;
+		}
+	}
+
 	/* 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;
 	}
 
@@ -445,12 +464,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);
@@ -459,6 +513,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[] = {
@@ -469,6 +525,8 @@ static struct attribute *dbs_attributes[] = {
 	&ignore_nice.attr,
 	&powersave_bias.attr,
 	&io_is_busy.attr,
+	&grad_up_threshold.attr,
+	&early_demand.attr,
 	NULL
 };
 
@@ -516,9 +574,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);
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v2 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-21 11:31   ` [PATCH v2 " Stratos Karafotis
@ 2013-02-21 15:33     ` Viresh Kumar
  2013-02-21 17:39       ` [PATCH v3 " Stratos Karafotis
  0 siblings, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2013-02-21 15:33 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Rafael J. Wysocki, cpufreq, linux-pm, linux-kernel

Hi Again,

On Thu, Feb 21, 2013 at 5:01 PM, Stratos Karafotis
<stratosk@semaphore.gr> wrote:

> diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> @@ -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;
> +               }
> +       }
> +
>         /* 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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-21 15:33     ` Viresh Kumar
@ 2013-02-21 17:39       ` Stratos Karafotis
  2013-02-22  1:56         ` Viresh Kumar
  0 siblings, 1 reply; 13+ messages in thread
From: Stratos Karafotis @ 2013-02-21 17:39 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: Rafael J. Wysocki, cpufreq, linux-pm, linux-kernel

Hi,

On 02/21/2013 05:33 PM, Viresh Kumar wrote:
> 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;
> 
> 
> 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.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 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(-)

diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 7722505..e737aa9 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -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);
 		}
 
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 6301790..3a703b9 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -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 {
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index c5fd794..fa4b21e 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -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 =
@@ -445,12 +461,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);
@@ -459,6 +510,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[] = {
@@ -469,6 +522,8 @@ static struct attribute *dbs_attributes[] = {
 	&ignore_nice.attr,
 	&powersave_bias.attr,
 	&io_is_busy.attr,
+	&grad_up_threshold.attr,
+	&early_demand.attr,
 	NULL
 };
 
@@ -516,9 +571,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);
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-21 17:39       ` [PATCH v3 " Stratos Karafotis
@ 2013-02-22  1:56         ` Viresh Kumar
  2013-02-22  5:57           ` Viresh Kumar
  2013-03-29 22:27           ` Stratos Karafotis
  0 siblings, 2 replies; 13+ messages in thread
From: Viresh Kumar @ 2013-02-22  1:56 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Rafael J. Wysocki, cpufreq, linux-pm, linux-kernel

On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:
> 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.
>
> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-22  1:56         ` Viresh Kumar
@ 2013-02-22  5:57           ` Viresh Kumar
  2013-02-22 12:47             ` Rafael J. Wysocki
  2013-03-29 22:27           ` Stratos Karafotis
  1 sibling, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2013-02-22  5:57 UTC (permalink / raw)
  To: Rafael J. Wysocki, Stratos Karafotis; +Cc: cpufreq, linux-pm, linux-kernel

On Fri, Feb 22, 2013 at 7:26 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:

>> 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.
>>
>> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-22  5:57           ` Viresh Kumar
@ 2013-02-22 12:47             ` Rafael J. Wysocki
  0 siblings, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2013-02-22 12:47 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: Stratos Karafotis, cpufreq, linux-pm, linux-kernel

On Friday, February 22, 2013 11:27:09 AM Viresh Kumar wrote:
> On Fri, Feb 22, 2013 at 7:26 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:
> 
> >> 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.
> >>
> >> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> >
> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> 
> 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


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-02-22  1:56         ` Viresh Kumar
  2013-02-22  5:57           ` Viresh Kumar
@ 2013-03-29 22:27           ` Stratos Karafotis
  2013-03-29 22:38             ` Rafael J. Wysocki
  2013-04-02 13:50             ` Rafael J. Wysocki
  1 sibling, 2 replies; 13+ messages in thread
From: Stratos Karafotis @ 2013-03-29 22:27 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Viresh Kumar, cpufreq, linux-pm, linux-kernel

On 02/22/2013 03:56 AM, Viresh Kumar wrote:
> On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:
>
>> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> 
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> 

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.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 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(-)

diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 41e5e56..1d9abc4 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -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);
 		}
 
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 1f7de13..c33b37a 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -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 {
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 29ed48a..6cd59a7 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -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);
-- 
1.8.1.4



^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-03-29 22:27           ` Stratos Karafotis
@ 2013-03-29 22:38             ` Rafael J. Wysocki
  2013-04-02 13:50             ` Rafael J. Wysocki
  1 sibling, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2013-03-29 22:38 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Viresh Kumar, cpufreq, linux-pm, linux-kernel

On Saturday, March 30, 2013 12:27:34 AM Stratos Karafotis wrote:
> On 02/22/2013 03:56 AM, Viresh Kumar wrote:
> > On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:
> >
> >> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> > 
> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> > 
> 
> 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


> ------------------------------------------
> 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.
> 
> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> ---
>  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(-)
> 
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 41e5e56..1d9abc4 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -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);
>  		}
>  
> diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
> index 1f7de13..c33b37a 100644
> --- a/drivers/cpufreq/cpufreq_governor.h
> +++ b/drivers/cpufreq/cpufreq_governor.h
> @@ -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 {
> diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> index 29ed48a..6cd59a7 100644
> --- a/drivers/cpufreq/cpufreq_ondemand.c
> +++ b/drivers/cpufreq/cpufreq_ondemand.c
> @@ -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);
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-03-29 22:27           ` Stratos Karafotis
  2013-03-29 22:38             ` Rafael J. Wysocki
@ 2013-04-02 13:50             ` Rafael J. Wysocki
  2013-04-02 15:49               ` Stratos Karafotis
  1 sibling, 1 reply; 13+ messages in thread
From: Rafael J. Wysocki @ 2013-04-02 13:50 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Viresh Kumar, cpufreq, linux-pm, linux-kernel

On Saturday, March 30, 2013 12:27:34 AM Stratos Karafotis wrote:
> On 02/22/2013 03:56 AM, Viresh Kumar wrote:
> > On 21 February 2013 23:09, Stratos Karafotis <stratosk@semaphore.gr> wrote:
> >
> >> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> > 
> > Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> > 
> 
> 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.

Do you have any numbers indicating that this actually makes things better?

Rafael


> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> ---
>  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(-)
> 
> diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
> index 41e5e56..1d9abc4 100644
> --- a/drivers/cpufreq/cpufreq_governor.c
> +++ b/drivers/cpufreq/cpufreq_governor.c
> @@ -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);
>  		}
>  
> diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
> index 1f7de13..c33b37a 100644
> --- a/drivers/cpufreq/cpufreq_governor.h
> +++ b/drivers/cpufreq/cpufreq_governor.h
> @@ -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 {
> diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> index 29ed48a..6cd59a7 100644
> --- a/drivers/cpufreq/cpufreq_ondemand.c
> +++ b/drivers/cpufreq/cpufreq_ondemand.c
> @@ -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);
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-04-02 13:50             ` Rafael J. Wysocki
@ 2013-04-02 15:49               ` Stratos Karafotis
  2013-04-02 22:55                 ` Rafael J. Wysocki
  0 siblings, 1 reply; 13+ messages in thread
From: Stratos Karafotis @ 2013-04-02 15:49 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Viresh Kumar, cpufreq, linux-pm, linux-kernel

On 04/02/2013 04:50 PM, Rafael J. Wysocki wrote:
> 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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency
  2013-04-02 15:49               ` Stratos Karafotis
@ 2013-04-02 22:55                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2013-04-02 22:55 UTC (permalink / raw)
  To: Stratos Karafotis; +Cc: Viresh Kumar, cpufreq, linux-pm, linux-kernel

On Tuesday, April 02, 2013 06:49:14 PM Stratos Karafotis wrote:
> On 04/02/2013 04:50 PM, Rafael J. Wysocki wrote:
> > 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?

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


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-04-02 22:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-20 20:50 [PATCH linux-next] cpufreq: ondemand: Calculate gradient of CPU load to early increase frequency Stratos Karafotis
2013-02-21  4:59 ` Viresh Kumar
2013-02-21 11:31   ` [PATCH v2 " Stratos Karafotis
2013-02-21 15:33     ` Viresh Kumar
2013-02-21 17:39       ` [PATCH v3 " Stratos Karafotis
2013-02-22  1:56         ` Viresh Kumar
2013-02-22  5:57           ` Viresh Kumar
2013-02-22 12:47             ` Rafael J. Wysocki
2013-03-29 22:27           ` Stratos Karafotis
2013-03-29 22:38             ` Rafael J. Wysocki
2013-04-02 13:50             ` Rafael J. Wysocki
2013-04-02 15:49               ` Stratos Karafotis
2013-04-02 22:55                 ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).