* [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition()
@ 2013-11-30 15:56 Viresh Kumar
2013-11-30 15:56 ` [PATCH 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-11-30 15:56 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 in case of failures. This is useful
at multiple places, specially for sending transition failure notifications.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
Hi Rafael,
Please see if you want to take it for 3.13 or 14, as this fixes bugs which are
partly introduced in 3.13..
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 606224a..a862aa9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -324,6 +324,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 ee5fe9d..57e48db 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -314,6 +314,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] 7+ messages in thread
* [PATCH 2/5] cpufreq: send new set of notification for transition failures
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
@ 2013-11-30 15:56 ` Viresh Kumar
2013-11-30 15:56 ` [PATCH 3/5] cpufreq: pcc: " Viresh Kumar
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-11-30 15:56 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 a862aa9..557bb49 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1764,17 +1764,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] 7+ messages in thread
* [PATCH 3/5] cpufreq: pcc: send new set of notification for transition failures
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
2013-11-30 15:56 ` [PATCH 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
@ 2013-11-30 15:56 ` Viresh Kumar
2013-11-30 15:56 ` [PATCH 4/5] cpufreq: powernow-k8: " Viresh Kumar
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-11-30 15:56 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] 7+ messages in thread
* [PATCH 4/5] cpufreq: powernow-k8: send new set of notification for transition failures
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
2013-11-30 15:56 ` [PATCH 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
2013-11-30 15:56 ` [PATCH 3/5] cpufreq: pcc: " Viresh Kumar
@ 2013-11-30 15:56 ` Viresh Kumar
2013-11-30 15:56 ` [PATCH 5/5] cpufreq: unicore2: " Viresh Kumar
2013-11-30 20:20 ` [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-11-30 15:56 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] 7+ messages in thread
* [PATCH 5/5] cpufreq: unicore2: send new set of notification for transition failures
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
` (2 preceding siblings ...)
2013-11-30 15:56 ` [PATCH 4/5] cpufreq: powernow-k8: " Viresh Kumar
@ 2013-11-30 15:56 ` Viresh Kumar
2013-11-30 20:20 ` [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
4 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-11-30 15:56 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 | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c
index 653ae29..3e79dae 100644
--- a/drivers/cpufreq/unicore2-cpufreq.c
+++ b/drivers/cpufreq/unicore2-cpufreq.c
@@ -49,17 +49,16 @@ static int ucv2_target(struct cpufreq_policy *policy,
unsigned int cur = ucv2_getspeed(0);
struct cpufreq_freqs freqs;
struct clk *mclk = clk_get(NULL, "MAIN_CLK");
+ int ret;
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
- if (!clk_set_rate(mclk, target_freq * 1000)) {
- freqs.old = cur;
- freqs.new = target_freq;
- }
+ freqs.old = cur;
+ freqs.new = target_freq;
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+ ret = clk_set_rate(mclk, 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] 7+ messages in thread
* Re: [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition()
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
` (3 preceding siblings ...)
2013-11-30 15:56 ` [PATCH 5/5] cpufreq: unicore2: " Viresh Kumar
@ 2013-11-30 20:20 ` Rafael J. Wysocki
2013-12-01 2:48 ` Viresh Kumar
4 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2013-11-30 20:20 UTC (permalink / raw)
To: Viresh Kumar; +Cc: linaro-kernel, patches, cpufreq, linux-pm, linux-kernel
On Saturday, November 30, 2013 09:26:19 PM 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 in case of failures. This is useful
> at multiple places, specially for sending transition failure notifications.
>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>
> Hi Rafael,
>
> Please see if you want to take it for 3.13 or 14, as this fixes bugs which are
> partly introduced in 3.13..
Which ones?
Rafael
> 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 606224a..a862aa9 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -324,6 +324,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 ee5fe9d..57e48db 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -314,6 +314,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] 7+ messages in thread
* Re: [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition()
2013-11-30 20:20 ` [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
@ 2013-12-01 2:48 ` Viresh Kumar
0 siblings, 0 replies; 7+ messages in thread
From: Viresh Kumar @ 2013-12-01 2:48 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Lists linaro-kernel, Patch Tracking, cpufreq@vger.kernel.org,
linux-pm@vger.kernel.org, Linux Kernel Mailing List
On 1 December 2013 01:50, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Saturday, November 30, 2013 09:26:19 PM 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 in case of failures. This is useful
>> at multiple places, specially for sending transition failure notifications.
>>
>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>> ---
>>
>> Hi Rafael,
>>
>> Please see if you want to take it for 3.13 or 14, as this fixes bugs which are
>> partly introduced in 3.13..
>
> Which ones?
Patch:
commit d4019f0a92ab802f385cc9c8ad3ab7b5449712cb
Author: Viresh Kumar <viresh.kumar@linaro.org>
Date: Wed Aug 14 19:38:24 2013 +0530
cpufreq: move freq change notifications to cpufreq core
adds:
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+ retval = cpufreq_driver->target_index(policy, index);
+ if (retval)
+ 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);
+ }
And I thought it might go in 3.13, but surely it doesn't fix any
obvious kernel crashes. It only fixes stuff when target_index() fails.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-12-01 2:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-30 15:56 [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Viresh Kumar
2013-11-30 15:56 ` [PATCH 2/5] cpufreq: send new set of notification for transition failures Viresh Kumar
2013-11-30 15:56 ` [PATCH 3/5] cpufreq: pcc: " Viresh Kumar
2013-11-30 15:56 ` [PATCH 4/5] cpufreq: powernow-k8: " Viresh Kumar
2013-11-30 15:56 ` [PATCH 5/5] cpufreq: unicore2: " Viresh Kumar
2013-11-30 20:20 ` [PATCH 1/5] cpufreq: Introduce cpufreq_notify_post_transition() Rafael J. Wysocki
2013-12-01 2:48 ` Viresh Kumar
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).