linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition()
@ 2013-12-02  5:34 Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:34 UTC (permalink / raw)
  To: rjw; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel,
	Viresh Kumar

This introduces another routine cpufreq_notify_post_transition() which can be
used to send POSTCHANGE notification for new freq with or without both
{PRE|POST}CHANGE notifications for last freq. This is useful at multiple places,
specially for sending transition failure notifications.

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

V1->V2:
- Not required to push it for 3.13 anymore and can go in 3.14.
- Rebased over following patchset as there were conflicts in unicore2 driver if
  following patchset is applied first (which should be the case):
  https://lkml.org/lkml/2013/10/30/553 (create cpufreq_generic_get() routine)

 drivers/cpufreq/cpufreq.c | 14 ++++++++++++++
 include/linux/cpufreq.h   |  2 ++
 2 files changed, 16 insertions(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 5e27def..3b877d4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -338,6 +338,20 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy,
 }
 EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
 
+/* Do post notifications when there are chances that transition has failed */
+void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+		struct cpufreq_freqs *freqs, int transition_failed)
+{
+	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
+	if (!transition_failed)
+		return;
+
+	swap(freqs->old, freqs->new);
+	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
+	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
+}
+EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
+
 
 /*********************************************************************
  *                          SYSFS INTERFACE                          *
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 276e646..b26bfab 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -316,6 +316,8 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
 
 void cpufreq_notify_transition(struct cpufreq_policy *policy,
 		struct cpufreq_freqs *freqs, unsigned int state);
+void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+		struct cpufreq_freqs *freqs, int transition_failed);
 
 #else /* CONFIG_CPU_FREQ */
 static inline int cpufreq_register_notifier(struct notifier_block *nb,
-- 
1.7.12.rc2.18.g61b472e


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

* [PATCH V2 2/5] cpufreq: send new set of notification for transition failures
  2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
@ 2013-12-02  5:34 ` Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 3/5] cpufreq: pcc: " Viresh Kumar
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:34 UTC (permalink / raw)
  To: rjw; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel,
	Viresh Kumar

In the current code, if we fail during a frequency transition we simply send the
POSTCHANGE notification with old frequency. This isn't enough.

One of the core user of these notifications is the code responsible for keeping
loops_per_jiffy aligned with frequency change. And mostly it is written as:

	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
		update-loops-per-jiffy...
	}

So, suppose we are changing to a higher frequency and failed during transition,
then following will happen:
- CPUFREQ_PRECHANGE notification with freq-new > freq-old
- CPUFREQ_POSTCHANGE notification with freq-new == freq-old

The first one will update loops_per_jiffy and second one will do nothing. Even
if we send the 2nd notification by exchanging values of freq-new and old, some
users of these notifications might get unstable.

This can be fixed by simply calling cpufreq_notify_post_transition() with error
code and this routine will take care of sending notifications in correct order.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/cpufreq.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3b877d4..a7fcb84 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1815,17 +1815,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
 			pr_err("%s: Failed to change cpu frequency: %d\n",
 					__func__, retval);
 
-		if (notify) {
-			/*
-			 * Notify with old freq in case we failed to change
-			 * frequency
-			 */
-			if (retval)
-				freqs.new = freqs.old;
-
-			cpufreq_notify_transition(policy, &freqs,
-					CPUFREQ_POSTCHANGE);
-		}
+		if (notify)
+			cpufreq_notify_post_transition(policy, &freqs, retval);
 	}
 
 out:
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 3/5] cpufreq: pcc: send new set of notification for transition failures
  2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
@ 2013-12-02  5:34 ` Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 4/5] cpufreq: powernow-k8: " Viresh Kumar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:34 UTC (permalink / raw)
  To: rjw; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel,
	Viresh Kumar

In the current code, if we fail during a frequency transition we simply send the
POSTCHANGE notification with old frequency. This isn't enough.

One of the core user of these notifications is the code responsible for keeping
loops_per_jiffy aligned with frequency change. And mostly it is written as:

	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
		update-loops-per-jiffy...
	}

So, suppose we are changing to a higher frequency and failed during transition,
then following will happen:
- CPUFREQ_PRECHANGE notification with freq-new > freq-old
- CPUFREQ_POSTCHANGE notification with freq-new == freq-old

The first one will update loops_per_jiffy and second one will do nothing. Even
if we send the 2nd notification by exchanging values of freq-new and old, some
users of these notifications might get unstable.

This can be fixed by simply calling cpufreq_notify_post_transition() with error
code and this routine will take care of sending notifications in correct order.

Also it fills freqs.old before starting the first notification, this was missing
since ever.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/pcc-cpufreq.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index e2b4f40..1c0f106 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -213,6 +213,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
 		cpu, target_freq,
 		(pcch_virt_addr + pcc_cpu_data->input_offset));
 
+	freqs.old = policy->cur;
 	freqs.new = target_freq;
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
@@ -228,25 +229,20 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
 	memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
 
 	status = ioread16(&pcch_hdr->status);
+	iowrite16(0, &pcch_hdr->status);
+
+	cpufreq_notify_post_transition(policy, &freqs, status != CMD_COMPLETE);
+	spin_unlock(&pcc_lock);
+
 	if (status != CMD_COMPLETE) {
 		pr_debug("target: FAILED for cpu %d, with status: 0x%x\n",
 			cpu, status);
-		goto cmd_incomplete;
+		return -EINVAL;
 	}
-	iowrite16(0, &pcch_hdr->status);
 
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 	pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu);
-	spin_unlock(&pcc_lock);
 
 	return 0;
-
-cmd_incomplete:
-	freqs.new = freqs.old;
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
-	iowrite16(0, &pcch_hdr->status);
-	spin_unlock(&pcc_lock);
-	return -EINVAL;
 }
 
 static int pcc_get_offset(int cpu)
-- 
1.7.12.rc2.18.g61b472e


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

* [PATCH V2 4/5] cpufreq: powernow-k8: send new set of notification for transition failures
  2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 3/5] cpufreq: pcc: " Viresh Kumar
@ 2013-12-02  5:34 ` Viresh Kumar
  2013-12-02  5:34 ` [PATCH V2 5/5] cpufreq: unicore2: " Viresh Kumar
  2014-01-06  1:16 ` [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
  4 siblings, 0 replies; 6+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:34 UTC (permalink / raw)
  To: rjw; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel,
	Viresh Kumar

In the current code, if we fail during a frequency transition we simply send the
POSTCHANGE notification with old frequency. This isn't enough.

One of the core user of these notifications is the code responsible for keeping
loops_per_jiffy aligned with frequency change. And mostly it is written as:

	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
		update-loops-per-jiffy...
	}

So, suppose we are changing to a higher frequency and failed during transition,
then following will happen:
- CPUFREQ_PRECHANGE notification with freq-new > freq-old
- CPUFREQ_POSTCHANGE notification with freq-new == freq-old

The first one will update loops_per_jiffy and second one will do nothing. Even
if we send the 2nd notification by exchanging values of freq-new and old, some
users of these notifications might get unstable.

This can be fixed by simply calling cpufreq_notify_post_transition() with error
code and this routine will take care of sending notifications in correct order.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/powernow-k8.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 0023c7d..e10b646 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -964,14 +964,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
 	cpufreq_cpu_put(policy);
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
 	res = transition_fid_vid(data, fid, vid);
-	if (res)
-		freqs.new = freqs.old;
-	else
-		freqs.new = find_khz_freq_from_fid(data->currfid);
+	cpufreq_notify_post_transition(policy, &freqs, res);
 
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
 	return res;
 }
 
-- 
1.7.12.rc2.18.g61b472e

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

* [PATCH V2 5/5] cpufreq: unicore2: send new set of notification for transition failures
  2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
                   ` (2 preceding siblings ...)
  2013-12-02  5:34 ` [PATCH V2 4/5] cpufreq: powernow-k8: " Viresh Kumar
@ 2013-12-02  5:34 ` Viresh Kumar
  2014-01-06  1:16 ` [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
  4 siblings, 0 replies; 6+ messages in thread
From: Viresh Kumar @ 2013-12-02  5:34 UTC (permalink / raw)
  To: rjw; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel,
	Viresh Kumar

In the current code, if we fail during a frequency transition we simply send the
POSTCHANGE notification with old frequency. This isn't enough.

One of the core user of these notifications is the code responsible for keeping
loops_per_jiffy aligned with frequency change. And mostly it is written as:

	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
		update-loops-per-jiffy...
	}

So, suppose we are changing to a higher frequency and failed during transition,
then following will happen:
- CPUFREQ_PRECHANGE notification with freq-new > freq-old
- CPUFREQ_POSTCHANGE notification with freq-new == freq-old

The first one will update loops_per_jiffy and second one will do nothing. Even
if we send the 2nd notification by exchanging values of freq-new and old, some
users of these notifications might get unstable.

This can be fixed by simply calling cpufreq_notify_post_transition() with error
code and this routine will take care of sending notifications in correct order.

Also it returns a proper error message in case frequency transition failed.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/cpufreq/unicore2-cpufreq.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c
index 951152f..99d280d6 100644
--- a/drivers/cpufreq/unicore2-cpufreq.c
+++ b/drivers/cpufreq/unicore2-cpufreq.c
@@ -38,19 +38,17 @@ static int ucv2_target(struct cpufreq_policy *policy,
 			 unsigned int target_freq,
 			 unsigned int relation)
 {
-	unsigned int cur = policy->cur;
 	struct cpufreq_freqs freqs;
+	int ret;
 
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
-	if (!clk_set_rate(policy->clk, target_freq * 1000)) {
-		freqs.old = cur;
-		freqs.new = target_freq;
-	}
+	freqs.old = policy->cur;
+	freqs.new = target_freq;
 
-	cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+	ret = clk_set_rate(policy->clk, target_freq * 1000);
+	cpufreq_notify_post_transition(policy, &freqs, ret);
 
-	return 0;
+	return ret;
 }
 
 static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
-- 
1.7.12.rc2.18.g61b472e


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

* Re: [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition()
  2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
                   ` (3 preceding siblings ...)
  2013-12-02  5:34 ` [PATCH V2 5/5] cpufreq: unicore2: " Viresh Kumar
@ 2014-01-06  1:16 ` Rafael J. Wysocki
  4 siblings, 0 replies; 6+ messages in thread
From: Rafael J. Wysocki @ 2014-01-06  1:16 UTC (permalink / raw)
  To: Viresh Kumar; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel

On Monday, December 02, 2013 11:04:12 AM Viresh Kumar wrote:
> This introduces another routine cpufreq_notify_post_transition() which can be
> used to send POSTCHANGE notification for new freq with or without both
> {PRE|POST}CHANGE notifications for last freq. This is useful at multiple places,
> specially for sending transition failure notifications.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

I've queued this series up for 3.14, but I folded patches [3-5/5] into [2/5]
(and needed to rebase the unicore2 changes).

Every time you want to copy-paste the changelog from one patch to another
(please don't do that any more) you should rather think about sending a
combination of the two as one patch.

Thanks!

> ---
> 
> V1->V2:
> - Not required to push it for 3.13 anymore and can go in 3.14.
> - Rebased over following patchset as there were conflicts in unicore2 driver if
>   following patchset is applied first (which should be the case):
>   https://lkml.org/lkml/2013/10/30/553 (create cpufreq_generic_get() routine)
> 
>  drivers/cpufreq/cpufreq.c | 14 ++++++++++++++
>  include/linux/cpufreq.h   |  2 ++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 5e27def..3b877d4 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -338,6 +338,20 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy,
>  }
>  EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
>  
> +/* Do post notifications when there are chances that transition has failed */
> +void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
> +		struct cpufreq_freqs *freqs, int transition_failed)
> +{
> +	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
> +	if (!transition_failed)
> +		return;
> +
> +	swap(freqs->old, freqs->new);
> +	cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
> +	cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
> +}
> +EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
> +
>  
>  /*********************************************************************
>   *                          SYSFS INTERFACE                          *
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 276e646..b26bfab 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -316,6 +316,8 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
>  
>  void cpufreq_notify_transition(struct cpufreq_policy *policy,
>  		struct cpufreq_freqs *freqs, unsigned int state);
> +void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
> +		struct cpufreq_freqs *freqs, int transition_failed);
>  
>  #else /* CONFIG_CPU_FREQ */
>  static inline int cpufreq_register_notifier(struct notifier_block *nb,
> 

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

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

end of thread, other threads:[~2014-01-06  1:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-02  5:34 [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
2013-12-02  5:34 ` [PATCH V2 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
2013-12-02  5:34 ` [PATCH V2 3/5] cpufreq: pcc: " Viresh Kumar
2013-12-02  5:34 ` [PATCH V2 4/5] cpufreq: powernow-k8: " Viresh Kumar
2013-12-02  5:34 ` [PATCH V2 5/5] cpufreq: unicore2: " Viresh Kumar
2014-01-06  1:16 ` [PATCH V2 1/5] cpufreq: Introduce cpufreq_notify_post_transition() 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).