[PATCH 2.6.25-rc1] cpufreq: fix cpufreq policy refcount imbalance

Yi Yang
2008-02-15T09:09:31Z

When one cpu is set to offline, the caller process will hang, according to
the trace data, the problem lies in the refcount error in cpufreq driver,
cpufreq_cpu_callback will wait for completion policy->kobj_unregister
which is nerver completed because a refcount error in function
__cpufreq_remove_dev in file driver/cpufreq/cpufreq.c results in not
calling kobject release method.

In driver/cpufreq/cpufreq.c, the refcount of data->kobj isn't 1 when it
will be unregistered, this problem didn't exist in 2.6.24 and earlier.

The root cause is kobject API switch, kobject_init_and_add and kobject_put
replace older kobject_register and kobject_unregister in 2.6.25-rc1,
compared to 2.6.24, kobject_unregister is deleted in function
__cpufreq_remove_dev but it isn't replaced with kobject_put.

This patch adds kobject_put to balance refcount. I noticed Greg suggests
it will fix a power-off issue to remove kobject_get statement block, but i
think that isn't the best way because those code block has existed very long
and it is helpful because the successive statements are invoking relevant
data.

Signed-off-by: Yi Yang <yi.y.yang@intel.com>
---
cpufreq.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/drivers/cpufreq/cpufreq.c 2008-02-15 04:41:29.000000000 +0800
+++ b/drivers/cpufreq/cpufreq.c 2008-02-15 06:56:56.000000000 +0800
@@ -1057,12 +1057,17 @@ static int __cpufreq_remove_dev (struct

unlock_policy_rwsem_write(cpu);

+ /* it matches the previous kobject_get */
kobject_put(&data->kobj);

/* we need to make sure that the underlying kobj is actually
* not referenced anymore by anybody before we proceed with
* unloading.
*/
+
+ /* unregister data->kobj, it matches kobject_init_and_add */
+ kobject_put(&data->kobj);
+
dprintk("waiting for dropping of refcount\n");
wait_for_completion(&data->kobj_unregister);
dprintk("wait complete\n");