Governors might use cpufreq_global_kobject when they don't have governor per policy. And so they must initialize it with a call to cpufreq_get_global_kobject(). Also after removing sysfs entries we must take the refcount down as well with a call to: cpufreq_put_global_kobject().
If above isn't done we will see following boot crash:
kernel BUG at /home/arm/work/kernel/mywork/linux.git/fs/sysfs/group.c:92! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-rc1-00852-g293953e-dirty #171 task: ee094000 ti: ee092000 task.ti: ee092000 PC is at internal_create_group+0x1f0/0x224 LR is at cpufreq_governor_interactive+0x13c/0x504 pc : [<c01094a0>] lr : [<c02aff44>] psr: 60000113 sp : ee093c90 ip : 00013880 fp : ee301368 r10: ee301300 r9 : c05084f0 r8 : c0531814 r7 : 00000000 r6 : ee105640 r5 : ee301300 r4 : ee105640 r3 : c0531a88 r2 : c0531814 r1 : 00000000 r0 : 00000000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 4000406a DAC: 00000015
<snip>
[<c01094a0>] (internal_create_group) from [<c02aff44>] (cpufreq_governor_interactive+0x13c/0x504) [<c02aff44>] (cpufreq_governor_interactive) from [<c02ab090>] (__cpufreq_governor+0x78/0x1f0) [<c02ab090>] (__cpufreq_governor) from [<c02ac224>] (cpufreq_set_policy+0x144/0x1c8) [<c02ac224>] (cpufreq_set_policy) from [<c02ac530>] (cpufreq_init_policy+0x54/0x80) [<c02ac530>] (cpufreq_init_policy) from [<c02ad8b0>] (__cpufreq_add_dev.isra.27+0x72c/0x804) [<c02ad8b0>] (__cpufreq_add_dev.isra.27) from [<c0223610>] (subsys_interface_register+0x80/0xc4) [<c0223610>] (subsys_interface_register) from [<c02ac890>] (cpufreq_register_driver+0xb8/0x214) [<c02ac890>] (cpufreq_register_driver) from [<c02b0744>] (exynos_cpufreq_probe+0xf4/0x1a0) [<c02b0744>] (exynos_cpufreq_probe) from [<c0225808>] (platform_drv_probe+0x18/0x48) [<c0225808>] (platform_drv_probe) from [<c0224498>] (driver_probe_device+0x100/0x218) [<c0224498>] (driver_probe_device) from [<c022463c>] (__driver_attach+0x8c/0x90) [<c022463c>] (__driver_attach) from [<c0222cb8>] (bus_for_each_dev+0x54/0x88) [<c0222cb8>] (bus_for_each_dev) from [<c0223c78>] (bus_add_driver+0xd4/0x1d0) [<c0223c78>] (bus_add_driver) from [<c0224c58>] (driver_register+0x78/0xf4) [<c0224c58>] (driver_register) from [<c0008854>] (do_one_initcall+0xe4/0x140) [<c0008854>] (do_one_initcall) from [<c04c8c68>] (kernel_init_freeable+0xfc/0x1c8) [<c04c8c68>] (kernel_init_freeable) from [<c0379abc>] (kernel_init+0x8/0x118) [<c0379abc>] (kernel_init) from [<c000e5f8>] (ret_from_fork+0x14/0x3c) Code: ebfc504c eaffffe0 e3500000 1affff8e (e7f001f2) ---[ end trace 04d313d9fc559575 ]--- Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org ---
Todd,
You need this patch for all kernels after 3.10. Not sure if android has already hit 3.11 or not.. Though I haven't seena a branch for that :)
drivers/cpufreq/cpufreq_interactive.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index ff77b30..5286e57 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1157,6 +1157,9 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, if (!have_governor_per_policy()) common_tunables = tunables;
+ if (!have_governor_per_policy()) + WARN_ON(cpufreq_get_global_kobject()); + rc = sysfs_create_group(get_governor_parent_kobj(policy), get_sysfs_attr()); if (rc) { @@ -1185,6 +1188,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
sysfs_remove_group(get_governor_parent_kobj(policy), get_sysfs_attr()); + + if (!have_governor_per_policy()) + cpufreq_put_global_kobject(); + kfree(tunables); common_tunables = NULL; }