diff options
author | Tomeu Vizoso <tomeu.vizoso@collabora.com> | 2014-11-24 04:08:03 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-25 16:44:17 -0500 |
commit | 6d4e81ed89c092cb156c8d19cb68c8733cd502b3 (patch) | |
tree | cdd76b6151008f5a1333055b781ac3d89337c4a6 | |
parent | f41f4815f8e81e8745fca8396d842adb74689c88 (diff) |
cpufreq: Ref the policy object sooner
Do it before it's assigned to cpufreq_cpu_data, otherwise when a driver
tries to get the cpu frequency during initialization the policy kobj is
referenced and we get this warning:
------------[ cut here ]------------
WARNING: CPU: 1 PID: 64 at include/linux/kref.h:47 kobject_get+0x64/0x70()
Modules linked in:
CPU: 1 PID: 64 Comm: irq/77-tegra-ac Not tainted 3.18.0-rc4-next-20141114ccu-00050-g3eff942 #326
[<c0016fac>] (unwind_backtrace) from [<c001272c>] (show_stack+0x10/0x14)
[<c001272c>] (show_stack) from [<c06085d8>] (dump_stack+0x98/0xd8)
[<c06085d8>] (dump_stack) from [<c002892c>] (warn_slowpath_common+0x84/0xb4)
[<c002892c>] (warn_slowpath_common) from [<c00289f8>] (warn_slowpath_null+0x1c/0x24)
[<c00289f8>] (warn_slowpath_null) from [<c0220290>] (kobject_get+0x64/0x70)
[<c0220290>] (kobject_get) from [<c03e944c>] (cpufreq_cpu_get+0x88/0xc8)
[<c03e944c>] (cpufreq_cpu_get) from [<c03e9500>] (cpufreq_get+0xc/0x64)
[<c03e9500>] (cpufreq_get) from [<c0285288>] (actmon_thread_isr+0x134/0x198)
[<c0285288>] (actmon_thread_isr) from [<c0069008>] (irq_thread_fn+0x1c/0x40)
[<c0069008>] (irq_thread_fn) from [<c0069324>] (irq_thread+0x134/0x174)
[<c0069324>] (irq_thread) from [<c0040290>] (kthread+0xdc/0xf4)
[<c0040290>] (kthread) from [<c000f4b8>] (ret_from_fork+0x14/0x3c)
---[ end trace b7bd64a81b340c59 ]---
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c9701e9e53e4..de2c3e198b62 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -900,46 +900,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | |||
900 | struct freq_attr **drv_attr; | 900 | struct freq_attr **drv_attr; |
901 | int ret = 0; | 901 | int ret = 0; |
902 | 902 | ||
903 | /* prepare interface data */ | ||
904 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | ||
905 | &dev->kobj, "cpufreq"); | ||
906 | if (ret) | ||
907 | return ret; | ||
908 | |||
909 | /* set up files for this cpu device */ | 903 | /* set up files for this cpu device */ |
910 | drv_attr = cpufreq_driver->attr; | 904 | drv_attr = cpufreq_driver->attr; |
911 | while ((drv_attr) && (*drv_attr)) { | 905 | while ((drv_attr) && (*drv_attr)) { |
912 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | 906 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
913 | if (ret) | 907 | if (ret) |
914 | goto err_out_kobj_put; | 908 | return ret; |
915 | drv_attr++; | 909 | drv_attr++; |
916 | } | 910 | } |
917 | if (cpufreq_driver->get) { | 911 | if (cpufreq_driver->get) { |
918 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | 912 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); |
919 | if (ret) | 913 | if (ret) |
920 | goto err_out_kobj_put; | 914 | return ret; |
921 | } | 915 | } |
922 | 916 | ||
923 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | 917 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
924 | if (ret) | 918 | if (ret) |
925 | goto err_out_kobj_put; | 919 | return ret; |
926 | 920 | ||
927 | if (cpufreq_driver->bios_limit) { | 921 | if (cpufreq_driver->bios_limit) { |
928 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); | 922 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); |
929 | if (ret) | 923 | if (ret) |
930 | goto err_out_kobj_put; | 924 | return ret; |
931 | } | 925 | } |
932 | 926 | ||
933 | ret = cpufreq_add_dev_symlink(policy); | 927 | return cpufreq_add_dev_symlink(policy); |
934 | if (ret) | ||
935 | goto err_out_kobj_put; | ||
936 | |||
937 | return ret; | ||
938 | |||
939 | err_out_kobj_put: | ||
940 | kobject_put(&policy->kobj); | ||
941 | wait_for_completion(&policy->kobj_unregister); | ||
942 | return ret; | ||
943 | } | 928 | } |
944 | 929 | ||
945 | static void cpufreq_init_policy(struct cpufreq_policy *policy) | 930 | static void cpufreq_init_policy(struct cpufreq_policy *policy) |
@@ -1198,6 +1183,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1198 | goto err_set_policy_cpu; | 1183 | goto err_set_policy_cpu; |
1199 | } | 1184 | } |
1200 | 1185 | ||
1186 | down_write(&policy->rwsem); | ||
1187 | |||
1201 | /* related cpus should atleast have policy->cpus */ | 1188 | /* related cpus should atleast have policy->cpus */ |
1202 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | 1189 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); |
1203 | 1190 | ||
@@ -1210,9 +1197,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1210 | if (!recover_policy) { | 1197 | if (!recover_policy) { |
1211 | policy->user_policy.min = policy->min; | 1198 | policy->user_policy.min = policy->min; |
1212 | policy->user_policy.max = policy->max; | 1199 | policy->user_policy.max = policy->max; |
1200 | |||
1201 | /* prepare interface data */ | ||
1202 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | ||
1203 | &dev->kobj, "cpufreq"); | ||
1204 | if (ret) { | ||
1205 | pr_err("%s: failed to init policy->kobj: %d\n", | ||
1206 | __func__, ret); | ||
1207 | goto err_init_policy_kobj; | ||
1208 | } | ||
1213 | } | 1209 | } |
1214 | 1210 | ||
1215 | down_write(&policy->rwsem); | ||
1216 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1211 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1217 | for_each_cpu(j, policy->cpus) | 1212 | for_each_cpu(j, policy->cpus) |
1218 | per_cpu(cpufreq_cpu_data, j) = policy; | 1213 | per_cpu(cpufreq_cpu_data, j) = policy; |
@@ -1303,6 +1298,11 @@ err_get_freq: | |||
1303 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1298 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1304 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1299 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1305 | 1300 | ||
1301 | if (!recover_policy) { | ||
1302 | kobject_put(&policy->kobj); | ||
1303 | wait_for_completion(&policy->kobj_unregister); | ||
1304 | } | ||
1305 | err_init_policy_kobj: | ||
1306 | up_write(&policy->rwsem); | 1306 | up_write(&policy->rwsem); |
1307 | 1307 | ||
1308 | if (cpufreq_driver->exit) | 1308 | if (cpufreq_driver->exit) |