Skip to content

Commit

Permalink
ANDROID: cpufreq: stats: Fix sleeping while atomic in cpufreq_task_st…
Browse files Browse the repository at this point in the history
…ats_init

With CONFIG_DEBUG_PREEMPT=y and CONFIG_DEBUG_ATOMIC_SLEEP=y, the
following splat happens on boot:

[   49.246119] c1   5125 BUG: sleeping function called from invalid context at mm/slab.h:363
[   49.246336] c1   5125 in_atomic(): 1, irqs_disabled(): 0, pid: 5125, name: Binder:5113_1
[   49.260434] Preemption disabled at:[<ffffff9037ea58a0>] copy_process.isra.63+0x4a0/0x17b8
[   49.271719] c1   5125
[   49.276367] c1   5125 CPU: 1 PID: 5125 Comm: Binder:5113_1 Not tainted 4.4.88-gb8b73b309f97 AEXmod#1
[   49.278828] c1   5125 Hardware name: Qualcomm Technologies, Inc. MSM8998 v2.1 (DT)
[   49.287408] c1   5125 Call trace:
[   49.294918] c1   5125 [<ffffff9037e8aa68>] dump_backtrace+0x0/0x228
[   49.298327] c1   5125 [<ffffff9037e8ad8c>] show_stack+0x14/0x1c
[   49.304432] c1   5125 [<ffffff903819eb24>] dump_stack+0x8c/0xb0
[   49.310312] c1   5125 [<ffffff9037ed6b0c>] ___might_sleep+0x15c/0x170
[   49.316219] c1   5125 [<ffffff9037ed6b70>] __might_sleep+0x50/0x84
[   49.322816] c1   5125 [<ffffff9037fea094>] __kmalloc+0x218/0x28c
[   49.328911] c1   5125 [<ffffff9038893154>] cpufreq_task_stats_init+0x64/0x90
[   49.335047] c1   5125 [<ffffff9037edb2dc>] sched_fork+0x74/0x288
[   49.342130] c1   5125 [<ffffff9037ea58a0>] copy_process.isra.63+0x4a0/0x17b8
[   49.348130] c1   5125 [<ffffff9037ea6cd8>] _do_fork+0x6c/0x3f4
[   49.355127] c1   5125 [<ffffff9037ea7128>] SyS_clone+0x1c/0x24
[   49.360764] c1   5125 [<ffffff9037e8394c>] __sys_trace_return+0x0/0x4

cpufreq_task_stats_init() does a GFP_KERNEL allocation but sched_fork()
disables preemption via get_cpu() before calling __sched_fork() which
calls cpufreq_task_stats_init().

This fix changes the allocation to use GFP_ATOMIC. The allocation is around
400 bytes and if it fails, the code handles that condition by not logging
cpufreq stats for that task. If missing stats is a problem, we can move
the allocation outside of __sched_fork() and handle the idle task
special case.

Bug: 67715533
Change-Id: I37d7f7ece3b8c08d3b1756c441a57e6d4028d481
Signed-off-by: Siqi Lin <siqilin@google.com>
  • Loading branch information
Siqi Lin authored and bgcngm committed Mar 25, 2019
1 parent 6faa119 commit bd1f6b2
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/cpufreq/cpufreq_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ void cpufreq_task_stats_init(struct task_struct *p)
* cpus
*/
alloc_size = p->max_states * sizeof(p->time_in_state[0]);
temp = kzalloc(alloc_size, GFP_KERNEL);
temp = kzalloc(alloc_size, GFP_ATOMIC);

spin_lock_irqsave(&task_time_in_state_lock, flags);
p->time_in_state = temp;
Expand Down

0 comments on commit bd1f6b2

Please sign in to comment.