All of lore.kernel.org
 help / color / mirror / Atom feed
From: Quentin Perret <qperret@google.com>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Rafael Wysocki <rjw@rjwysocki.net>,
	linux-pm@vger.kernel.org,
	Vincent Guittot <vincent.guittot@linaro.org>,
	kernel-team@android.com, tkjos@google.com,
	adharmap@codeaurora.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH V3 1/3] cpufreq: Fix locking issues with governors
Date: Fri, 26 Jun 2020 09:24:33 +0100	[thread overview]
Message-ID: <20200626082433.GA284605@google.com> (raw)
In-Reply-To: <f366ed3dd3dd111e42173b366fe4dd5a0e4647fd.1593143118.git.viresh.kumar@linaro.org>

On Friday 26 Jun 2020 at 09:21:42 (+0530), Viresh Kumar wrote:
> The locking around governors handling isn't adequate currently. The list
> of governors should never be traversed without locking in place. Also we
> must make sure the governor isn't removed while it is still referenced
> by code.
> 
> Reported-by: Quentin Perret <qperret@google.com>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
>  drivers/cpufreq/cpufreq.c | 59 ++++++++++++++++++++++++---------------
>  1 file changed, 36 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 0128de3603df..e798a1193bdf 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -621,6 +621,24 @@ static struct cpufreq_governor *find_governor(const char *str_governor)
>  	return NULL;
>  }
>  
> +static struct cpufreq_governor *get_governor(const char *str_governor)
> +{
> +	struct cpufreq_governor *t;
> +
> +	mutex_lock(&cpufreq_governor_mutex);
> +	t = find_governor(str_governor);
> +	if (!t)
> +		goto unlock;
> +
> +	if (!try_module_get(t->owner))
> +		t = NULL;
> +
> +unlock:
> +	mutex_unlock(&cpufreq_governor_mutex);
> +
> +	return t;
> +}
> +
>  static unsigned int cpufreq_parse_policy(char *str_governor)
>  {
>  	if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN))
> @@ -640,28 +658,14 @@ static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor)
>  {
>  	struct cpufreq_governor *t;
>  
> -	mutex_lock(&cpufreq_governor_mutex);
> -
> -	t = find_governor(str_governor);
> -	if (!t) {
> -		int ret;
> -
> -		mutex_unlock(&cpufreq_governor_mutex);
> -
> -		ret = request_module("cpufreq_%s", str_governor);
> -		if (ret)
> -			return NULL;
> -
> -		mutex_lock(&cpufreq_governor_mutex);
> +	t = get_governor(str_governor);
> +	if (t)
> +		return t;
>  
> -		t = find_governor(str_governor);
> -	}
> -	if (t && !try_module_get(t->owner))
> -		t = NULL;
> -
> -	mutex_unlock(&cpufreq_governor_mutex);
> +	if (request_module("cpufreq_%s", str_governor))
> +		return NULL;
>  
> -	return t;
> +	return get_governor(str_governor);
>  }
>  
>  /**
> @@ -815,12 +819,14 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
>  		goto out;
>  	}
>  
> +	mutex_lock(&cpufreq_governor_mutex);
>  	for_each_governor(t) {
>  		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
>  		    - (CPUFREQ_NAME_LEN + 2)))
> -			goto out;
> +			break;
>  		i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
>  	}
> +	mutex_unlock(&cpufreq_governor_mutex);
>  out:
>  	i += sprintf(&buf[i], "\n");
>  	return i;
> @@ -1058,11 +1064,14 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  	struct cpufreq_governor *def_gov = cpufreq_default_governor();
>  	struct cpufreq_governor *gov = NULL;
>  	unsigned int pol = CPUFREQ_POLICY_UNKNOWN;
> +	bool put_governor = false;
> +	int ret;
>  
>  	if (has_target()) {
>  		/* Update policy governor to the one used before hotplug. */
> -		gov = find_governor(policy->last_governor);
> +		gov = get_governor(policy->last_governor);
>  		if (gov) {
> +			put_governor = true;
>  			pr_debug("Restoring governor %s for cpu %d\n",
>  				 policy->governor->name, policy->cpu);
>  		} else if (def_gov) {
> @@ -1089,7 +1098,11 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy)
>  			return -ENODATA;
>  	}
>  
> -	return cpufreq_set_policy(policy, gov, pol);
> +	ret = cpufreq_set_policy(policy, gov, pol);
> +	if (put_governor)
> +		module_put(gov->owner);

Nit: I think you could safely do

	if (gov)
		module_put(gov->owner);

and get rid of 'put_governor', given that try_module_get() and
module_put() are nops if owner is NULL (which is guaranteed for
the result of cpufreq_default_governor() as it is builtin).

But other than that:

Reviewed-by: Quentin Perret <qperret@google.com>

Thanks!

  reply	other threads:[~2020-06-26  8:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-26  3:51 [PATCH v3 0/3] cpufreq: Allow default governor on cmdline and fix locking issues Viresh Kumar
2020-06-26  3:51 ` Viresh Kumar
2020-06-26  3:51 ` [PATCH V3 1/3] cpufreq: Fix locking issues with governors Viresh Kumar
2020-06-26  8:24   ` Quentin Perret [this message]
2020-06-29  2:13     ` Viresh Kumar
2020-06-29  8:05       ` Quentin Perret
2020-06-29 13:13       ` Rafael J. Wysocki
2020-06-26  3:51 ` [PATCH V3 2/3] cpufreq: Register governors at core_initcall Viresh Kumar
2020-06-26  3:51   ` Viresh Kumar
2020-06-26  3:51 ` [PATCH V3 3/3] cpufreq: Specify default governor on command line Viresh Kumar
2020-06-26 15:57   ` Quentin Perret
2020-06-29  2:08     ` Viresh Kumar
2020-06-29  8:03       ` Quentin Perret

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200626082433.GA284605@google.com \
    --to=qperret@google.com \
    --cc=adharmap@codeaurora.org \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=tkjos@google.com \
    --cc=vincent.guittot@linaro.org \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.