linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] cpufreq: Initialize the governor again while restoring policy
@ 2015-07-08  5:53 Viresh Kumar
  2015-07-08  6:02 ` Pi-Cheng Chen
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Viresh Kumar @ 2015-07-08  5:53 UTC (permalink / raw)
  To: Rafael Wysocki
  Cc: linaro-kernel, linux-pm, Viresh Kumar, Pi-Cheng Chen,
	Jon Medhurst (Tixy), open list

When all CPUs of a policy are hot-unplugged, we EXIT the governor but
don't mark policy->governor as NULL. This was done in order to keep last
used governor's information intact in sysfs, while the CPUs are offline.

We also missed marking policy->governor as NULL while restoring the
policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)
for an uninitialized policy. Which eventually returns -EBUSY.

Fix this by setting policy->governor to NULL while restoring the policy.

Reported-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
Reported-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
For 4.2-rc

 drivers/cpufreq/cpufreq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b612411655f9..2c22e3902e72 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
 
 		down_write(&policy->rwsem);
 		policy->cpu = cpu;
+		policy->governor = NULL;
 		up_write(&policy->rwsem);
 	}
 
-- 
2.4.0


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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-08  5:53 [PATCH] cpufreq: Initialize the governor again while restoring policy Viresh Kumar
@ 2015-07-08  6:02 ` Pi-Cheng Chen
  2015-07-08  9:27 ` Jon Medhurst (Tixy)
  2015-07-09  0:33 ` Rafael J. Wysocki
  2 siblings, 0 replies; 8+ messages in thread
From: Pi-Cheng Chen @ 2015-07-08  6:02 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, Linaro Kernel Mailman List,
	linux-pm@vger.kernel.org, Jon Medhurst (Tixy), open list

On Wed, Jul 8, 2015 at 1:53 PM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> When all CPUs of a policy are hot-unplugged, we EXIT the governor but
> don't mark policy->governor as NULL. This was done in order to keep last
> used governor's information intact in sysfs, while the CPUs are offline.
>
> We also missed marking policy->governor as NULL while restoring the
> policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)
> for an uninitialized policy. Which eventually returns -EBUSY.
>
> Fix this by setting policy->governor to NULL while restoring the policy.

Tested-by: "Pi-Cheng Chen <pi-cheng.chen@linaro.org>"

Thanks for your fix.

>
> Reported-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
> Reported-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
> Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> For 4.2-rc
>
>  drivers/cpufreq/cpufreq.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index b612411655f9..2c22e3902e72 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
>
>                 down_write(&policy->rwsem);
>                 policy->cpu = cpu;
> +               policy->governor = NULL;
>                 up_write(&policy->rwsem);
>         }
>
> --
> 2.4.0
>

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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-08  5:53 [PATCH] cpufreq: Initialize the governor again while restoring policy Viresh Kumar
  2015-07-08  6:02 ` Pi-Cheng Chen
@ 2015-07-08  9:27 ` Jon Medhurst (Tixy)
  2015-07-08  9:29   ` Viresh Kumar
  2015-07-09  0:33 ` Rafael J. Wysocki
  2 siblings, 1 reply; 8+ messages in thread
From: Jon Medhurst (Tixy) @ 2015-07-08  9:27 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, linaro-kernel, linux-pm, Pi-Cheng Chen, open list

On Wed, 2015-07-08 at 11:23 +0530, Viresh Kumar wrote:
> When all CPUs of a policy are hot-unplugged, we EXIT the governor but
> don't mark policy->governor as NULL. This was done in order to keep last
> used governor's information intact in sysfs, while the CPUs are offline.
> 
> We also missed marking policy->governor as NULL while restoring the
> policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)
> for an uninitialized policy. Which eventually returns -EBUSY.
> 
> Fix this by setting policy->governor to NULL while restoring the policy.
> 
> Reported-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
> Reported-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
> Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---

Tested-by: Jon Medhurst <tixy@linaro.org>

Thanks for that.

I believe this also fixes the other issue I mentioned (nullptr deref in
in arm_big_little driver). To test that, after applying this patch, I
modified the code to force __cpufreq_governor to still return an error
when a cpu is hotpluged back in. Now the arm_big_little driver doesn't
get called when I manually poke scaling_setspeed, presumably because
policy->governor==NULL prevents that from reaching the driver?

> For 4.2-rc
> 
>  drivers/cpufreq/cpufreq.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index b612411655f9..2c22e3902e72 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
>  
>  		down_write(&policy->rwsem);
>  		policy->cpu = cpu;
> +		policy->governor = NULL;
>  		up_write(&policy->rwsem);
>  	}
>  



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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-08  9:27 ` Jon Medhurst (Tixy)
@ 2015-07-08  9:29   ` Viresh Kumar
  0 siblings, 0 replies; 8+ messages in thread
From: Viresh Kumar @ 2015-07-08  9:29 UTC (permalink / raw)
  To: Jon Medhurst (Tixy)
  Cc: Rafael Wysocki, linaro-kernel, linux-pm, Pi-Cheng Chen, open list

On 08-07-15, 10:27, Jon Medhurst (Tixy) wrote:
> I believe this also fixes the other issue I mentioned (nullptr deref in
> in arm_big_little driver). To test that, after applying this patch, I
> modified the code to force __cpufreq_governor to still return an error
> when a cpu is hotpluged back in. Now the arm_big_little driver doesn't
> get called when I manually poke scaling_setspeed, presumably because
> policy->governor==NULL prevents that from reaching the driver?

I would like to fix that issue without using this patch as we aren't
cleaning up things properly on errors today. I am almost done with the
patches, and will send them to you shortly. Please give them a try
without this patch.

-- 
viresh

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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-08  5:53 [PATCH] cpufreq: Initialize the governor again while restoring policy Viresh Kumar
  2015-07-08  6:02 ` Pi-Cheng Chen
  2015-07-08  9:27 ` Jon Medhurst (Tixy)
@ 2015-07-09  0:33 ` Rafael J. Wysocki
  2015-07-09  5:10   ` Viresh Kumar
  2 siblings, 1 reply; 8+ messages in thread
From: Rafael J. Wysocki @ 2015-07-09  0:33 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linaro-kernel, linux-pm, Pi-Cheng Chen, Jon Medhurst (Tixy),
	open list

On Wednesday, July 08, 2015 11:23:58 AM Viresh Kumar wrote:
> When all CPUs of a policy are hot-unplugged, we EXIT the governor but
> don't mark policy->governor as NULL. This was done in order to keep last
> used governor's information intact in sysfs, while the CPUs are offline.
> 
> We also missed marking policy->governor as NULL while restoring the
> policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)

How exactly does that happen?

> for an uninitialized policy. Which eventually returns -EBUSY.
> 
> Fix this by setting policy->governor to NULL while restoring the policy.
> 
> Reported-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
> Reported-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
> Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> For 4.2-rc
> 
>  drivers/cpufreq/cpufreq.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index b612411655f9..2c22e3902e72 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
>  
>  		down_write(&policy->rwsem);
>  		policy->cpu = cpu;
> +		policy->governor = NULL;
>  		up_write(&policy->rwsem);
>  	}
>  
> 

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

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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-09  0:33 ` Rafael J. Wysocki
@ 2015-07-09  5:10   ` Viresh Kumar
  2015-07-10  0:05     ` Rafael J. Wysocki
  0 siblings, 1 reply; 8+ messages in thread
From: Viresh Kumar @ 2015-07-09  5:10 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linaro-kernel, linux-pm, Pi-Cheng Chen, Jon Medhurst (Tixy),
	open list, Steven Rostedt

On 09-07-15, 02:33, Rafael J. Wysocki wrote:
> > We also missed marking policy->governor as NULL while restoring the
> > policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)
> 
> How exactly does that happen?

Should have mentioned that in detail, sorry for being lazy. Hopefully
this will look better:

---------------------------8<---------------------------

Message-Id: <5f17361741c009a7f0d8488f7f94bab80d9317fd.1436418101.git.viresh.kumar@linaro.org>
From: Viresh Kumar <viresh.kumar@linaro.org>
Date: Wed, 8 Jul 2015 10:45:53 +0530
Subject: [PATCH V2] cpufreq: Initialize the governor again while restoring policy

When all CPUs of a policy are hot-unplugged, we EXIT the governor but
don't mark policy->governor as NULL. This was done in order to keep last
used governor's information intact in sysfs, while the CPUs are offline.

But we also marking policy->governor as NULL while restoring the policy.

Because policy->governor still points to the last governor while policy
is restored, following sequence of event happens:
- cpufreq_init_policy() called while restoring policy
- find_governor() matches last_governor string for present governors and
  returns last used governor's pointer, say ondemand. policy->governor
  already has the same address, unless the governor was removed in
  between.
- cpufreq_set_policy() is called with both old/new policies governor set
  as ondemand.
- Because governors matched, we skip governor initialization and return
  after calling __cpufreq_governor(CPUFREQ_GOV_LIMITS). Because the
  governor wasn't initialized for this policy, it returned -EBUSY.
- cpufreq_init_policy() exits the policy on this error, but doesn't
  destroy it properly (should be fixed separately).
- And so we enter a scenario where the policy isn't completely
  initialized but used.

Fix this by setting policy->governor to NULL while restoring the policy.

Reported-and-tested-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
Reported-and-tested-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
Tested-by: Steven Rostedt <rostedt@goodmis.org>
Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2: Detailed changelog

 drivers/cpufreq/cpufreq.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b612411655f9..2c22e3902e72 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
 
 		down_write(&policy->rwsem);
 		policy->cpu = cpu;
+		policy->governor = NULL;
 		up_write(&policy->rwsem);
 	}

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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-09  5:10   ` Viresh Kumar
@ 2015-07-10  0:05     ` Rafael J. Wysocki
  2015-07-10  3:38       ` Viresh Kumar
  0 siblings, 1 reply; 8+ messages in thread
From: Rafael J. Wysocki @ 2015-07-10  0:05 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linaro-kernel, linux-pm, Pi-Cheng Chen, Jon Medhurst (Tixy),
	open list, Steven Rostedt

On Thursday, July 09, 2015 10:40:24 AM Viresh Kumar wrote:
> On 09-07-15, 02:33, Rafael J. Wysocki wrote:
> > > We also missed marking policy->governor as NULL while restoring the
> > > policy. Because of that, we call __cpufreq_governor(CPUFREQ_GOV_LIMITS)
> > 
> > How exactly does that happen?
> 
> Should have mentioned that in detail, sorry for being lazy. Hopefully
> this will look better:

OK, applied (with some minor changelog fixup), thanks!


> ---------------------------8<---------------------------
> 
> Message-Id: <5f17361741c009a7f0d8488f7f94bab80d9317fd.1436418101.git.viresh.kumar@linaro.org>
> From: Viresh Kumar <viresh.kumar@linaro.org>
> Date: Wed, 8 Jul 2015 10:45:53 +0530
> Subject: [PATCH V2] cpufreq: Initialize the governor again while restoring policy
> 
> When all CPUs of a policy are hot-unplugged, we EXIT the governor but
> don't mark policy->governor as NULL. This was done in order to keep last
> used governor's information intact in sysfs, while the CPUs are offline.
> 
> But we also marking policy->governor as NULL while restoring the policy.
> 
> Because policy->governor still points to the last governor while policy
> is restored, following sequence of event happens:
> - cpufreq_init_policy() called while restoring policy
> - find_governor() matches last_governor string for present governors and
>   returns last used governor's pointer, say ondemand. policy->governor
>   already has the same address, unless the governor was removed in
>   between.
> - cpufreq_set_policy() is called with both old/new policies governor set
>   as ondemand.
> - Because governors matched, we skip governor initialization and return
>   after calling __cpufreq_governor(CPUFREQ_GOV_LIMITS).

But this sounds fragile in principle.  What's the benefit from skipping the
governor initialization in that case?


>   Because the
>   governor wasn't initialized for this policy, it returned -EBUSY.
> - cpufreq_init_policy() exits the policy on this error, but doesn't
>   destroy it properly (should be fixed separately).
> - And so we enter a scenario where the policy isn't completely
>   initialized but used.
> 
> Fix this by setting policy->governor to NULL while restoring the policy.
> 
> Reported-and-tested-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
> Reported-and-tested-by: "Jon Medhurst (Tixy)" <tixy@linaro.org>
> Tested-by: Steven Rostedt <rostedt@goodmis.org>
> Fixes: 18bf3a124ef8 ("cpufreq: Mark policy->governor = NULL for inactive policies")
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V2: Detailed changelog
> 
>  drivers/cpufreq/cpufreq.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index b612411655f9..2c22e3902e72 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1132,6 +1132,7 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
>  
>  		down_write(&policy->rwsem);
>  		policy->cpu = cpu;
> +		policy->governor = NULL;
>  		up_write(&policy->rwsem);
>  	}

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

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

* Re: [PATCH] cpufreq: Initialize the governor again while restoring policy
  2015-07-10  0:05     ` Rafael J. Wysocki
@ 2015-07-10  3:38       ` Viresh Kumar
  0 siblings, 0 replies; 8+ messages in thread
From: Viresh Kumar @ 2015-07-10  3:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linaro Kernel Mailman List, linux-pm@vger.kernel.org,
	Pi-Cheng Chen, Jon Medhurst (Tixy), open list, Steven Rostedt

On 10 July 2015 at 05:35, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:

>> - Because governors matched, we skip governor initialization and return
>>   after calling __cpufreq_governor(CPUFREQ_GOV_LIMITS).
>
> But this sounds fragile in principle.  What's the benefit from skipping the
> governor initialization in that case?

So this is the case where we have changed some property of the governor,
and the governor is already initialised. We need to exit the earlier governor
and initialize the new one only when the governor is actually switched.

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

end of thread, other threads:[~2015-07-10  3:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-08  5:53 [PATCH] cpufreq: Initialize the governor again while restoring policy Viresh Kumar
2015-07-08  6:02 ` Pi-Cheng Chen
2015-07-08  9:27 ` Jon Medhurst (Tixy)
2015-07-08  9:29   ` Viresh Kumar
2015-07-09  0:33 ` Rafael J. Wysocki
2015-07-09  5:10   ` Viresh Kumar
2015-07-10  0:05     ` Rafael J. Wysocki
2015-07-10  3:38       ` 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).