From: Stephen Boyd Date: Wed, 6 Aug 2014 20:04:58 +0000 (+0200) Subject: cpufreq: OPP: Avoid sleeping while atomic X-Git-Tag: firefly_0821_release~176^2~3381^2~1^3~2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3c5445ce3a0c6d6935911212b735772af5115517;p=firefly-linux-kernel-4.4.55.git cpufreq: OPP: Avoid sleeping while atomic We allocate the cpufreq table after calling rcu_read_lock(), which disables preemption. This causes scheduling while atomic warnings. Use GFP_ATOMIC instead of GFP_KERNEL and update for kcalloc while we're here. BUG: sleeping function called from invalid context at mm/slub.c:1246 in_atomic(): 0, irqs_disabled(): 0, pid: 80, name: modprobe 5 locks held by modprobe/80: #0: (&dev->mutex){......}, at: [] __driver_attach+0x48/0x98 #1: (&dev->mutex){......}, at: [] __driver_attach+0x58/0x98 #2: (subsys mutex#5){+.+.+.}, at: [] subsys_interface_register+0x38/0xc8 #3: (cpufreq_rwsem){.+.+.+}, at: [] __cpufreq_add_dev.isra.22+0x84/0x92c #4: (rcu_read_lock){......}, at: [] dev_pm_opp_init_cpufreq_table+0x18/0x10c Preemption disabled at:[< (null)>] (null) CPU: 2 PID: 80 Comm: modprobe Not tainted 3.16.0-rc3-next-20140701-00035-g286857f216aa-dirty #217 [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x70/0xbc) [] (dump_stack) from [] (__kmalloc+0x124/0x250) [] (__kmalloc) from [] (dev_pm_opp_init_cpufreq_table+0x3c/0x10c) [] (dev_pm_opp_init_cpufreq_table) from [] (cpufreq_init+0x48/0x378 [cpufreq_generic]) [] (cpufreq_init [cpufreq_generic]) from [] (__cpufreq_add_dev.isra.22+0x200/0x92c) [] (__cpufreq_add_dev.isra.22) from [] (subsys_interface_register+0x84/0xc8) [] (subsys_interface_register) from [] (cpufreq_register_driver+0x108/0x2d8) [] (cpufreq_register_driver) from [] (generic_cpufreq_probe+0x50/0x74 [cpufreq_generic]) [] (generic_cpufreq_probe [cpufreq_generic]) from [] (platform_drv_probe+0x18/0x48) [] (platform_drv_probe) from [] (driver_probe_device+0x128/0x370) [] (driver_probe_device) from [] (__driver_attach+0x94/0x98) [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xe8/0x204) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (do_one_initcall+0xac/0x1d8) [] (do_one_initcall) from [] (load_module+0x190c/0x21e8) [] (load_module) from [] (SyS_init_module+0xa4/0x110) [] (SyS_init_module) from [] (ret_fast_syscall+0x0/0x48) Fixes: a0dd7b79657b (PM / OPP: Move cpufreq specific OPP functions out of generic OPP library) Signed-off-by: Stephen Boyd Acked-by: Viresh Kumar Cc: 3.16+ # 3.16+ Signed-off-by: Rafael J. Wysocki --- diff --git a/drivers/cpufreq/cpufreq_opp.c b/drivers/cpufreq/cpufreq_opp.c index c0c6f4a4eccf..f7a32d2326c6 100644 --- a/drivers/cpufreq/cpufreq_opp.c +++ b/drivers/cpufreq/cpufreq_opp.c @@ -60,7 +60,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, goto out; } - freq_table = kzalloc(sizeof(*freq_table) * (max_opps + 1), GFP_KERNEL); + freq_table = kcalloc(sizeof(*freq_table), (max_opps + 1), GFP_ATOMIC); if (!freq_table) { ret = -ENOMEM; goto out;