All of lore.kernel.org
 help / color / mirror / Atom feed
From: Prarit Bhargava <prarit@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: robert.schoene@tu-dresden.de, sboyd@codeaurora.org,
	Prarit Bhargava <prarit@redhat.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>,
	Viresh Kumar <viresh.kumar@linaro.org>,
	linux-pm@vger.kernel.org
Subject: [PATCH 4/5] cpufreq, policy->initialized count must be atomic
Date: Wed,  5 Nov 2014 09:53:58 -0500	[thread overview]
Message-ID: <1415199239-19019-5-git-send-email-prarit@redhat.com> (raw)
In-Reply-To: <1415199239-19019-1-git-send-email-prarit@redhat.com>

The policy->initialized value can be modified from several cpus concurrently if
!CPUFREQ_HAVE_GOVERNOR_PER_POLICY.  This leads to a situation where a
governor maybe switched out even though the governor->initialized is greater
than one.  It must be switched to atomic_t and protected with a mutex to
make sure that future read/writes obtain the correct data.

Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: linux-pm@vger.kernel.org
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
---
 drivers/cpufreq/cpufreq.c          |   12 +++++++++---
 drivers/cpufreq/cpufreq_governor.c |    4 ++--
 include/linux/cpufreq.h            |    3 ++-
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e33cb15..cf11de6 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2059,10 +2059,12 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
 	ret = policy->governor->governor(policy, event);
 
 	if (!ret) {
+		mutex_lock(&policy->governor->initialized_mutex);
 		if (event == CPUFREQ_GOV_POLICY_INIT)
-			policy->governor->initialized++;
+			atomic_inc(&policy->governor->initialized);
 		else if (event == CPUFREQ_GOV_POLICY_EXIT)
-			policy->governor->initialized--;
+			atomic_dec(&policy->governor->initialized);
+		mutex_unlock(&policy->governor->initialized_mutex);
 	} else {
 		/* Restore original values */
 		mutex_lock(&cpufreq_governor_lock);
@@ -2092,7 +2094,11 @@ int cpufreq_register_governor(struct cpufreq_governor *governor)
 
 	mutex_lock(&cpufreq_governor_mutex);
 
-	governor->initialized = 0;
+	mutex_init(&governor->initialized_mutex);
+	mutex_lock(&governor->initialized_mutex);
+	atomic_set(&governor->initialized, 0);
+	mutex_unlock(&governor->initialized_mutex);
+
 	err = -EBUSY;
 	if (__find_governor(governor->name) == NULL) {
 		err = 0;
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index 32ad9db..b1ee597 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -315,7 +315,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 					latency * LATENCY_MULTIPLIER));
 
 		if ((cdata->governor == GOV_CONSERVATIVE) &&
-				(!policy->governor->initialized)) {
+		    (!atomic_read(&policy->governor->initialized))) {
 			struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
 
 			cpufreq_register_notifier(cs_ops->notifier_block,
@@ -336,7 +336,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 				cpufreq_put_global_kobject();
 
 			if ((dbs_data->cdata->governor == GOV_CONSERVATIVE) &&
-				(policy->governor->initialized == 1)) {
+			    atomic_read(&policy->governor->initialized) == 1) {
 				struct cs_ops *cs_ops = dbs_data->cdata->gov_ops;
 
 				cpufreq_unregister_notifier(cs_ops->notifier_block,
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 43909ad..73cec45 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -431,7 +431,8 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
 
 struct cpufreq_governor {
 	char	name[CPUFREQ_NAME_LEN];
-	int	initialized;
+	struct mutex initialized_mutex;
+	atomic_t initialized;
 	int	(*governor)	(struct cpufreq_policy *policy,
 				 unsigned int event);
 	ssize_t	(*show_setspeed)	(struct cpufreq_policy *policy,
-- 
1.7.9.3

  parent reply	other threads:[~2014-11-05 14:53 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-05 14:53 [PATCH 0/5] cpufreq, fix locking and data issues Prarit Bhargava
2014-11-05 14:53 ` [PATCH 1/5] cpufreq, do not return stale data to userspace Prarit Bhargava
2014-11-05 14:53 ` [PATCH 2/5] cpufreq, fix locking around CPUFREQ_GOV_POLICY_EXIT calls Prarit Bhargava
2014-11-10 10:44   ` Viresh Kumar
2014-11-10 12:26     ` Prarit Bhargava
2014-11-11  3:37       ` Viresh Kumar
2014-11-11 12:15         ` Prarit Bhargava
2014-11-11 13:07           ` Viresh Kumar
2014-11-13 21:58             ` Saravana Kannan
2014-11-05 14:53 ` [PATCH 3/5] cpufreq, dbs_data->usage count must be atomic Prarit Bhargava
2014-11-08  1:57   ` Rafael J. Wysocki
2014-11-11  3:40   ` Viresh Kumar
2014-11-05 14:53 ` Prarit Bhargava [this message]
2014-11-08  1:59   ` [PATCH 4/5] cpufreq, policy->initialized " Rafael J. Wysocki
2014-11-11  3:55   ` Viresh Kumar
2014-11-05 14:53 ` [PATCH 5/5] cpufreq, add BUG() messages in critical paths to aid debugging failures Prarit Bhargava
2014-11-08  2:00   ` Rafael J. Wysocki
2014-11-08 13:33     ` Prarit Bhargava
2014-11-08 21:46       ` Rafael J. Wysocki
2014-11-09 14:12         ` Prarit Bhargava
2014-11-11  4:23   ` Viresh Kumar
2014-11-11 12:18     ` Prarit Bhargava
2014-11-11 13:11       ` Viresh Kumar

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=1415199239-19019-5-git-send-email-prarit@redhat.com \
    --to=prarit@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=rjw@rjwysocki.net \
    --cc=robert.schoene@tu-dresden.de \
    --cc=sboyd@codeaurora.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.