Commit 6d4e81ed89c092cb156c8d19cb68c8733cd502b3
Committed by
Rafael J. Wysocki
1 parent
f41f4815f8
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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>
Showing 1 changed file with 21 additions and 21 deletions Side-by-side Diff
drivers/cpufreq/cpufreq.c
... | ... | @@ -900,46 +900,31 @@ |
900 | 900 | struct freq_attr **drv_attr; |
901 | 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 | 903 | /* set up files for this cpu device */ |
910 | 904 | drv_attr = cpufreq_driver->attr; |
911 | 905 | while ((drv_attr) && (*drv_attr)) { |
912 | 906 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
913 | 907 | if (ret) |
914 | - goto err_out_kobj_put; | |
908 | + return ret; | |
915 | 909 | drv_attr++; |
916 | 910 | } |
917 | 911 | if (cpufreq_driver->get) { |
918 | 912 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); |
919 | 913 | if (ret) |
920 | - goto err_out_kobj_put; | |
914 | + return ret; | |
921 | 915 | } |
922 | 916 | |
923 | 917 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
924 | 918 | if (ret) |
925 | - goto err_out_kobj_put; | |
919 | + return ret; | |
926 | 920 | |
927 | 921 | if (cpufreq_driver->bios_limit) { |
928 | 922 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); |
929 | 923 | if (ret) |
930 | - goto err_out_kobj_put; | |
924 | + return ret; | |
931 | 925 | } |
932 | 926 | |
933 | - ret = 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; | |
927 | + return cpufreq_add_dev_symlink(policy); | |
943 | 928 | } |
944 | 929 | |
945 | 930 | static void cpufreq_init_policy(struct cpufreq_policy *policy) |
... | ... | @@ -1198,6 +1183,8 @@ |
1198 | 1183 | goto err_set_policy_cpu; |
1199 | 1184 | } |
1200 | 1185 | |
1186 | + down_write(&policy->rwsem); | |
1187 | + | |
1201 | 1188 | /* related cpus should atleast have policy->cpus */ |
1202 | 1189 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); |
1203 | 1190 | |
1204 | 1191 | |
... | ... | @@ -1210,9 +1197,17 @@ |
1210 | 1197 | if (!recover_policy) { |
1211 | 1198 | policy->user_policy.min = policy->min; |
1212 | 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 | 1211 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1217 | 1212 | for_each_cpu(j, policy->cpus) |
1218 | 1213 | per_cpu(cpufreq_cpu_data, j) = policy; |
... | ... | @@ -1303,6 +1298,11 @@ |
1303 | 1298 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1304 | 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 | 1306 | up_write(&policy->rwsem); |
1307 | 1307 | |
1308 | 1308 | if (cpufreq_driver->exit) |