[08/10] cpufreq: Fix broken usage of governor->owner's refcount

Message ID 46faea4c060f91f7102d9d33c816693acc25a917.1375530162.git.viresh.kumar@linaro.org
State New
Headers show

Commit Message

Viresh Kumar Aug. 3, 2013, 11:49 a.m.
Governor's owner refcount usage was broken. We should increment refcount only
when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
CPUFREQ_GOV_POLICY_EXIT has come.

Lets fix it.

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

Comments

Rafael J. Wysocki Aug. 3, 2013, 12:08 p.m. | #1
On Saturday, August 03, 2013 05:19:26 PM Viresh Kumar wrote:
> Governor's owner refcount usage was broken. We should increment refcount only
> when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
> CPUFREQ_GOV_POLICY_EXIT has come.
> 
> Lets fix it.

OK, and what happens if we don't fix it?

Rafael


> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/cpufreq/cpufreq.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index e9b969f..74d4969 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1707,8 +1707,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
>  		}
>  	}
>  
> -	if (!try_module_get(policy->governor->owner))
> -		return -EINVAL;
> +	if (event == CPUFREQ_GOV_POLICY_INIT)
> +		if (!try_module_get(policy->governor->owner))
> +			return -EINVAL;
>  
>  	pr_debug("__cpufreq_governor for CPU %u, event %u\n",
>  						policy->cpu, event);
> @@ -1717,6 +1718,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
>  	if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
>  	    (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
>  		mutex_unlock(&cpufreq_governor_lock);
> +		if (event == CPUFREQ_GOV_POLICY_INIT)
> +			module_put(policy->governor->owner);
>  		return -EBUSY;
>  	}
>  
> @@ -1744,11 +1747,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
>  		mutex_unlock(&cpufreq_governor_lock);
>  	}
>  
> -	/* we keep one module reference alive for
> -			each CPU governed by this CPU */
> -	if ((event != CPUFREQ_GOV_START) || ret)
> -		module_put(policy->governor->owner);
> -	if ((event == CPUFREQ_GOV_STOP) && !ret)
> +	if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
> +			((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
>  		module_put(policy->governor->owner);
>  
>  	return ret;
>
Viresh Kumar Aug. 3, 2013, 1:27 p.m. | #2
On 3 August 2013 17:38, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday, August 03, 2013 05:19:26 PM Viresh Kumar wrote:
>> Governor's owner refcount usage was broken. We should increment refcount only
>> when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
>> CPUFREQ_GOV_POLICY_EXIT has come.
>>
>> Lets fix it.
>
> OK, and what happens if we don't fix it?

What about this changelog:

Subject: [PATCH 08/10] cpufreq: Fix broken usage of governor->owner's
 refcount

Governor's owner refcount usage was broken. We should increment refcount only
when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
CPUFREQ_GOV_POLICY_EXIT has come.

Currently there can be situations where governor is in use but we have allowed
it to be unloaded. And that may cause in undefined behavior.

Lets fix it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Rafael J. Wysocki Aug. 3, 2013, 10:06 p.m. | #3
On Saturday, August 03, 2013 06:57:11 PM Viresh Kumar wrote:
> On 3 August 2013 17:38, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Saturday, August 03, 2013 05:19:26 PM Viresh Kumar wrote:
> >> Governor's owner refcount usage was broken. We should increment refcount only
> >> when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
> >> CPUFREQ_GOV_POLICY_EXIT has come.
> >>
> >> Lets fix it.
> >
> > OK, and what happens if we don't fix it?
> 
> What about this changelog:
> 
> Subject: [PATCH 08/10] cpufreq: Fix broken usage of governor->owner's
>  refcount
> 
> Governor's owner refcount usage was broken. We should increment refcount only
> when CPUFREQ_GOV_POLICY_INIT event has come and should decrement only if
> CPUFREQ_GOV_POLICY_EXIT has come.
> 
> Currently there can be situations where governor is in use but we have allowed
> it to be unloaded. And that may cause in undefined behavior.

"it to be unloaded which may result in undefined behavior."

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

Apart from the above looks good.

Thanks,
Rafael

Patch

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e9b969f..74d4969 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1707,8 +1707,9 @@  static int __cpufreq_governor(struct cpufreq_policy *policy,
 		}
 	}
 
-	if (!try_module_get(policy->governor->owner))
-		return -EINVAL;
+	if (event == CPUFREQ_GOV_POLICY_INIT)
+		if (!try_module_get(policy->governor->owner))
+			return -EINVAL;
 
 	pr_debug("__cpufreq_governor for CPU %u, event %u\n",
 						policy->cpu, event);
@@ -1717,6 +1718,8 @@  static int __cpufreq_governor(struct cpufreq_policy *policy,
 	if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
 	    (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
 		mutex_unlock(&cpufreq_governor_lock);
+		if (event == CPUFREQ_GOV_POLICY_INIT)
+			module_put(policy->governor->owner);
 		return -EBUSY;
 	}
 
@@ -1744,11 +1747,8 @@  static int __cpufreq_governor(struct cpufreq_policy *policy,
 		mutex_unlock(&cpufreq_governor_lock);
 	}
 
-	/* we keep one module reference alive for
-			each CPU governed by this CPU */
-	if ((event != CPUFREQ_GOV_START) || ret)
-		module_put(policy->governor->owner);
-	if ((event == CPUFREQ_GOV_STOP) && !ret)
+	if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
+			((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
 		module_put(policy->governor->owner);
 
 	return ret;