lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAKohpom0-Z+s4G+OOhVZJn=HK7NVKHCXS-_0FJd07K+L5DwgHA@mail.gmail.com>
Date:	Thu, 13 Jun 2013 11:22:04 +0530
From:	Viresh Kumar <viresh.kumar@...aro.org>
To:	Xiaoguang Chen <chenxg.marvell@...il.com>
Cc:	Xiaoguang Chen <chenxg@...vell.com>,
	"Rafael J. Wysocki" <rjw@...k.pl>, cpufreq@...r.kernel.org,
	linux-pm@...r.kernel.org,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	njiang1@...vell.com, zjwu@...vell.com, ylmao@...vell.com
Subject: Re: [PATCH v4] cpufreq: fix governor start/stop race condition

On 13 June 2013 11:10, Xiaoguang Chen <chenxg.marvell@...il.com> wrote:
> 2013/6/12 Viresh Kumar <viresh.kumar@...aro.org>:
>> On 12 June 2013 14:39, Xiaoguang Chen <chenxg@...vell.com> wrote:
>>
>>>         ret = policy->governor->governor(policy, event);
>>
>> We again reached to the same problem. We shouldn't call
>> this between taking locks, otherwise recursive locks problems
>> would be seen again.
>
> But this is not the same lock as the deadlock case, it is a new lock,
> and only used in this function. no other functions use this lock.
> I don't know how can we get dead lock again?

I believe I have seen the recursive lock issue with different locks but
I am not sure. Anyway, I believe the implementation can be simpler than
that.

Check below patch (attached too):

------------x------------------x----------------

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 2d53f47..80b9798 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -46,6 +46,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *,
cpufreq_cpu_data);
 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
 #endif
 static DEFINE_RWLOCK(cpufreq_driver_lock);
+static DEFINE_MUTEX(cpufreq_governor_lock);

 /*
  * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
@@ -1541,7 +1542,6 @@ static int __cpufreq_governor(struct
cpufreq_policy *policy,
 #else
 	struct cpufreq_governor *gov = NULL;
 #endif
-
 	if (policy->governor->max_transition_latency &&
 	    policy->cpuinfo.transition_latency >
 	    policy->governor->max_transition_latency) {
@@ -1562,6 +1562,21 @@ static int __cpufreq_governor(struct
cpufreq_policy *policy,

 	pr_debug("__cpufreq_governor for CPU %u, event %u\n",
 						policy->cpu, event);
+
+	mutex_lock(&cpufreq_governor_lock);
+	if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
+	    (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
+		mutex_unlock(&cpufreq_governor_lock);
+		return -EBUSY;
+	}
+
+	if (event == CPUFREQ_GOV_STOP)
+		policy->governor_enabled = 0;
+	else if (event == CPUFREQ_GOV_START)
+		policy->governor_enabled = 1;
+
+	mutex_unlock(&cpufreq_governor_lock);
+
 	ret = policy->governor->governor(policy, event);

 	if (!ret) {
@@ -1569,6 +1584,14 @@ static int __cpufreq_governor(struct
cpufreq_policy *policy,
 			policy->governor->initialized++;
 		else if (event == CPUFREQ_GOV_POLICY_EXIT)
 			policy->governor->initialized--;
+	} else {
+		/* Restore original values */
+		mutex_lock(&cpufreq_governor_lock);
+		if (event == CPUFREQ_GOV_STOP)
+			policy->governor_enabled = 1;
+		else if (event == CPUFREQ_GOV_START)
+			policy->governor_enabled = 0;
+		mutex_unlock(&cpufreq_governor_lock);
 	}

 	/* we keep one module reference alive for
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 037d36a..c12db73 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -107,6 +107,7 @@ struct cpufreq_policy {
 	unsigned int		policy; /* see above */
 	struct cpufreq_governor	*governor; /* see below */
 	void			*governor_data;
+	int			governor_enabled; /* governor start/stop flag */

 	struct work_struct	update; /* if update_policy() needs to be
 					 * called, but you're in IRQ context */

Download attachment "0001-cpufreq-fix-governor-start-stop-race-condition.patch" of type "application/octet-stream" (4321 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ