From: Mathieu Desnoyers <mathieu.desnoyers-scC8bbJcJLCw5LPnMra/2Q@public.gmane.org>
To: venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org
Cc: Dave Jones <davej-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
cpufreq-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
kernel-testers-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Ingo Molnar <mingo-X9Un+BFzKDI@public.gmane.org>,
"Rafael J. Wysocki" <rjw-KKrjLPT3xs0@public.gmane.org>,
Dave Young
<hidave.darkstar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
Pekka Enberg <penberg-bbCR+/B0CizivPeTLB3BmA@public.gmane.org>,
Thomas Renninger <trenn-l3A5Bk7waGM@public.gmane.org>
Subject: [PATCH] CPUFREQ: fix (utter) cpufreq_add_dev mess v1
Date: Thu, 2 Jul 2009 22:23:47 -0400 [thread overview]
Message-ID: <20090703022346.GA26976@Krystal> (raw)
In-Reply-To: <20090703000829.735976000-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
(Can you give this patch a try and review my locking fixes ? I'm
uncomfortable modifying cpufreq locking before getting this fix correct
in the first place)
OK, I've tried to clean it up the best I could, but please test this with
concurrent cpu hotplug and cpufreq add/remove in loops. I'm sure we will make
other interesting findings.
This is step one of fixing the overall cpufreq locking dependency mess.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers-scC8bbJcJLCw5LPnMra/2Q@public.gmane.org>
CC: "Pallipadi, Venkatesh" <venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
CC: Dave Jones <davej-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
CC: Ingo Molnar <mingo-X9Un+BFzKDI@public.gmane.org>
CC: "Rafael J. Wysocki" <rjw-KKrjLPT3xs0@public.gmane.org>
CC: Dave Young <hidave.darkstar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
CC: Pekka Enberg <penberg-bbCR+/B0CizivPeTLB3BmA@public.gmane.org>
CC: Thomas Renninger <trenn-l3A5Bk7waGM@public.gmane.org>
---
drivers/cpufreq/cpufreq.c | 65 ++++++++++++++++++++++++++++------------------
1 file changed, 40 insertions(+), 25 deletions(-)
Index: linux-2.6-lttng/drivers/cpufreq/cpufreq.c
===================================================================
--- linux-2.6-lttng.orig/drivers/cpufreq/cpufreq.c 2009-07-02 20:47:19.000000000 -0400
+++ linux-2.6-lttng/drivers/cpufreq/cpufreq.c 2009-07-02 21:52:56.000000000 -0400
@@ -763,6 +763,10 @@ static struct kobj_type ktype_cpufreq =
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
*/
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
@@ -806,15 +810,12 @@ static int cpufreq_add_dev(struct sys_de
goto nomem_out;
}
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_policy;
}
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
- free_cpumask_var(policy->cpus);
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_cpumask;
}
policy->cpu = cpu;
@@ -822,7 +823,8 @@ static int cpufreq_add_dev(struct sys_de
/* Initially set CPU itself as the policy_cpu */
per_cpu(policy_cpu, cpu) = cpu;
- lock_policy_rwsem_write(cpu);
+ ret = (lock_policy_rwsem_write(cpu) < 0);
+ WARN_ON(ret);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update);
@@ -835,7 +837,7 @@ static int cpufreq_add_dev(struct sys_de
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
- goto err_out;
+ goto err_unlock_policy;
}
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
@@ -860,15 +862,21 @@ static int cpufreq_add_dev(struct sys_de
/* Check for existing affected CPUs.
* They may not be aware of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
+ managed_policy = cpufreq_cpu_get(j);
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
unlock_policy_rwsem_write(cpu);
per_cpu(policy_cpu, cpu) = managed_policy->cpu;
- if (lock_policy_rwsem_write(cpu) < 0)
- goto err_out_driver_exit;
+ if (lock_policy_rwsem_write(cpu) < 0) {
+ /* Should not go through policy unlock path */
+ if (cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
+ ret = -EBUSY;
+ cpufreq_cpu_put(managed_policy);
+ goto err_free_cpumask;
+ }
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpumask_copy(managed_policy->cpus, policy->cpus);
@@ -879,12 +887,14 @@ static int cpufreq_add_dev(struct sys_de
ret = sysfs_create_link(&sys_dev->kobj,
&managed_policy->kobj,
"cpufreq");
- if (ret)
- goto err_out_driver_exit;
-
- cpufreq_debug_enable_ratelimit();
- ret = 0;
- goto err_out_driver_exit; /* call driver->exit() */
+ if (!ret)
+ cpufreq_cpu_put(managed_policy);
+ /*
+ * Success. We only needed to be added to the mask.
+ * Call driver->exit() because only the cpu parent of
+ * the kobj needed to call init().
+ */
+ goto out_driver_exit; /* call driver->exit() */
}
}
#endif
@@ -894,25 +904,25 @@ static int cpufreq_add_dev(struct sys_de
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
"cpufreq");
if (ret)
- goto err_out_driver_exit;
+ goto out_driver_exit;
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
while ((drv_attr) && (*drv_attr)) {
ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
drv_attr++;
}
if (cpufreq_driver->get) {
ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
if (cpufreq_driver->target) {
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -930,12 +940,14 @@ static int cpufreq_add_dev(struct sys_de
continue;
dprintk("CPU %u already managed, adding link\n", j);
- cpufreq_cpu_get(cpu);
+ managed_policy = cpufreq_cpu_get(cpu);
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
- if (ret)
+ if (ret) {
+ cpufreq_cpu_put(managed_policy);
goto err_out_unregister;
+ }
}
policy->governor = NULL; /* to assure that the starting sequence is
@@ -967,17 +979,20 @@ err_out_unregister:
per_cpu(cpufreq_cpu_data, j) = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+err_out_kobj_put:
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
-err_out_driver_exit:
+out_driver_exit:
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
-err_out:
+err_unlock_policy:
unlock_policy_rwsem_write(cpu);
+err_free_cpumask:
+ free_cpumask_var(policy->cpus);
+err_free_policy:
kfree(policy);
-
nomem_out:
module_put(cpufreq_driver->owner);
module_out:
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
WARNING: multiple messages have this Message-ID (diff)
From: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
To: venkatesh.pallipadi@intel.com
Cc: Dave Jones <davej@redhat.com>,
linux-kernel@vger.kernel.org, cpufreq@vger.kernel.org,
kernel-testers@vger.kernel.org, Ingo Molnar <mingo@elte.hu>,
"Rafael J. Wysocki" <rjw@sisk.pl>,
Dave Young <hidave.darkstar@gmail.com>,
Pekka Enberg <penberg@cs.helsinki.fi>,
Thomas Renninger <trenn@suse.de>
Subject: [PATCH] CPUFREQ: fix (utter) cpufreq_add_dev mess v1
Date: Thu, 2 Jul 2009 22:23:47 -0400 [thread overview]
Message-ID: <20090703022346.GA26976@Krystal> (raw)
In-Reply-To: <20090703000829.735976000@intel.com>
(Can you give this patch a try and review my locking fixes ? I'm
uncomfortable modifying cpufreq locking before getting this fix correct
in the first place)
OK, I've tried to clean it up the best I could, but please test this with
concurrent cpu hotplug and cpufreq add/remove in loops. I'm sure we will make
other interesting findings.
This is step one of fixing the overall cpufreq locking dependency mess.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
CC: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
CC: Dave Jones <davej@redhat.com>,
CC: Ingo Molnar <mingo@elte.hu>
CC: "Rafael J. Wysocki" <rjw@sisk.pl>
CC: Dave Young <hidave.darkstar@gmail.com>
CC: Pekka Enberg <penberg@cs.helsinki.fi>
CC: Thomas Renninger <trenn@suse.de>
---
drivers/cpufreq/cpufreq.c | 65 ++++++++++++++++++++++++++++------------------
1 file changed, 40 insertions(+), 25 deletions(-)
Index: linux-2.6-lttng/drivers/cpufreq/cpufreq.c
===================================================================
--- linux-2.6-lttng.orig/drivers/cpufreq/cpufreq.c 2009-07-02 20:47:19.000000000 -0400
+++ linux-2.6-lttng/drivers/cpufreq/cpufreq.c 2009-07-02 21:52:56.000000000 -0400
@@ -763,6 +763,10 @@ static struct kobj_type ktype_cpufreq =
* cpufreq_add_dev - add a CPU device
*
* Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
*/
static int cpufreq_add_dev(struct sys_device *sys_dev)
{
@@ -806,15 +810,12 @@ static int cpufreq_add_dev(struct sys_de
goto nomem_out;
}
if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_policy;
}
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
- free_cpumask_var(policy->cpus);
- kfree(policy);
ret = -ENOMEM;
- goto nomem_out;
+ goto err_free_cpumask;
}
policy->cpu = cpu;
@@ -822,7 +823,8 @@ static int cpufreq_add_dev(struct sys_de
/* Initially set CPU itself as the policy_cpu */
per_cpu(policy_cpu, cpu) = cpu;
- lock_policy_rwsem_write(cpu);
+ ret = (lock_policy_rwsem_write(cpu) < 0);
+ WARN_ON(ret);
init_completion(&policy->kobj_unregister);
INIT_WORK(&policy->update, handle_update);
@@ -835,7 +837,7 @@ static int cpufreq_add_dev(struct sys_de
ret = cpufreq_driver->init(policy);
if (ret) {
dprintk("initialization failed\n");
- goto err_out;
+ goto err_unlock_policy;
}
policy->user_policy.min = policy->min;
policy->user_policy.max = policy->max;
@@ -860,15 +862,21 @@ static int cpufreq_add_dev(struct sys_de
/* Check for existing affected CPUs.
* They may not be aware of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
+ managed_policy = cpufreq_cpu_get(j);
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
unlock_policy_rwsem_write(cpu);
per_cpu(policy_cpu, cpu) = managed_policy->cpu;
- if (lock_policy_rwsem_write(cpu) < 0)
- goto err_out_driver_exit;
+ if (lock_policy_rwsem_write(cpu) < 0) {
+ /* Should not go through policy unlock path */
+ if (cpufreq_driver->exit)
+ cpufreq_driver->exit(policy);
+ ret = -EBUSY;
+ cpufreq_cpu_put(managed_policy);
+ goto err_free_cpumask;
+ }
spin_lock_irqsave(&cpufreq_driver_lock, flags);
cpumask_copy(managed_policy->cpus, policy->cpus);
@@ -879,12 +887,14 @@ static int cpufreq_add_dev(struct sys_de
ret = sysfs_create_link(&sys_dev->kobj,
&managed_policy->kobj,
"cpufreq");
- if (ret)
- goto err_out_driver_exit;
-
- cpufreq_debug_enable_ratelimit();
- ret = 0;
- goto err_out_driver_exit; /* call driver->exit() */
+ if (!ret)
+ cpufreq_cpu_put(managed_policy);
+ /*
+ * Success. We only needed to be added to the mask.
+ * Call driver->exit() because only the cpu parent of
+ * the kobj needed to call init().
+ */
+ goto out_driver_exit; /* call driver->exit() */
}
}
#endif
@@ -894,25 +904,25 @@ static int cpufreq_add_dev(struct sys_de
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
"cpufreq");
if (ret)
- goto err_out_driver_exit;
+ goto out_driver_exit;
/* set up files for this cpu device */
drv_attr = cpufreq_driver->attr;
while ((drv_attr) && (*drv_attr)) {
ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
drv_attr++;
}
if (cpufreq_driver->get) {
ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
if (cpufreq_driver->target) {
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
- goto err_out_driver_exit;
+ goto err_out_kobj_put;
}
spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -930,12 +940,14 @@ static int cpufreq_add_dev(struct sys_de
continue;
dprintk("CPU %u already managed, adding link\n", j);
- cpufreq_cpu_get(cpu);
+ managed_policy = cpufreq_cpu_get(cpu);
cpu_sys_dev = get_cpu_sysdev(j);
ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
"cpufreq");
- if (ret)
+ if (ret) {
+ cpufreq_cpu_put(managed_policy);
goto err_out_unregister;
+ }
}
policy->governor = NULL; /* to assure that the starting sequence is
@@ -967,17 +979,20 @@ err_out_unregister:
per_cpu(cpufreq_cpu_data, j) = NULL;
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
+err_out_kobj_put:
kobject_put(&policy->kobj);
wait_for_completion(&policy->kobj_unregister);
-err_out_driver_exit:
+out_driver_exit:
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
-err_out:
+err_unlock_policy:
unlock_policy_rwsem_write(cpu);
+err_free_cpumask:
+ free_cpumask_var(policy->cpus);
+err_free_policy:
kfree(policy);
-
nomem_out:
module_put(cpufreq_driver->owner);
module_out:
--
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F BA06 3F25 A8FE 3BAE 9A68
next prev parent reply other threads:[~2009-07-03 2:23 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-03 0:08 [patch 0/4] Take care of cpufreq lockdep issues (take 2) venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w
2009-07-03 0:08 ` venkatesh.pallipadi
2009-07-03 0:08 ` [patch 1/4] cpufreq: Eliminate the recent lockdep warnings in cpufreq venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w
2009-07-03 0:08 ` venkatesh.pallipadi
[not found] ` <20090703000923.800507000-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2009-07-03 1:06 ` Mathieu Desnoyers
2009-07-03 1:06 ` Mathieu Desnoyers
2009-07-03 2:04 ` Pallipadi, Venkatesh
2009-07-03 2:04 ` Pallipadi, Venkatesh
[not found] ` <7E82351C108FA840AB1866AC776AEC4669BFEF78-osO9UTpF0URqS6EAlXoojrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2009-07-03 2:25 ` Mathieu Desnoyers
2009-07-03 2:25 ` Mathieu Desnoyers
2009-07-03 11:41 ` Thomas Renninger
2009-07-03 11:41 ` Thomas Renninger
[not found] ` <200907031341.19141.trenn-l3A5Bk7waGM@public.gmane.org>
2009-07-03 14:28 ` Pallipadi, Venkatesh
2009-07-03 14:28 ` Pallipadi, Venkatesh
[not found] ` <7E82351C108FA840AB1866AC776AEC4669BFF050-osO9UTpF0URqS6EAlXoojrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2009-07-06 11:19 ` Thomas Renninger
2009-07-06 11:19 ` Thomas Renninger
2009-07-03 0:08 ` [patch 2/4] cpufreq: Mark policy_rwsem as going static in cpufreq.c wont be exported venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w
2009-07-03 0:08 ` venkatesh.pallipadi
2009-07-03 0:08 ` [patch 3/4] cpufreq: Cleanup locking in ondemand governor venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w
2009-07-03 0:08 ` venkatesh.pallipadi
2009-07-03 0:08 ` [patch 4/4] cpufreq: Cleanup locking in conservative governor venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w
2009-07-03 0:08 ` venkatesh.pallipadi
[not found] ` <20090703000829.735976000-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2009-07-03 2:23 ` Mathieu Desnoyers [this message]
2009-07-03 2:23 ` [PATCH] CPUFREQ: fix (utter) cpufreq_add_dev mess v1 Mathieu Desnoyers
2009-07-03 6:54 ` [patch 0/4] Take care of cpufreq lockdep issues (take 2) Ingo Molnar
2009-07-03 6:54 ` Ingo Molnar
[not found] ` <20090703065427.GA32687-X9Un+BFzKDI@public.gmane.org>
2009-07-03 14:06 ` Mathieu Desnoyers
2009-07-03 14:06 ` Mathieu Desnoyers
2009-07-03 14:31 ` Pallipadi, Venkatesh
2009-07-03 14:31 ` Pallipadi, Venkatesh
[not found] ` <7E82351C108FA840AB1866AC776AEC4669BFF052-osO9UTpF0URqS6EAlXoojrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2009-07-03 18:48 ` Ingo Molnar
2009-07-03 18:48 ` Ingo Molnar
2009-07-06 18:52 ` Pallipadi, Venkatesh
2009-07-06 18:52 ` Pallipadi, Venkatesh
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=20090703022346.GA26976@Krystal \
--to=mathieu.desnoyers-scc8bbjcjlcw5lpnmra/2q@public.gmane.org \
--cc=cpufreq-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=davej-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=hidave.darkstar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=kernel-testers-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mingo-X9Un+BFzKDI@public.gmane.org \
--cc=penberg-bbCR+/B0CizivPeTLB3BmA@public.gmane.org \
--cc=rjw-KKrjLPT3xs0@public.gmane.org \
--cc=trenn-l3A5Bk7waGM@public.gmane.org \
--cc=venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.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.