Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a327eadc authored by Siqi Lin's avatar Siqi Lin Committed by Razziell
Browse files

ANDROID: cpufreq: stats: Fix sleeping while atomic in cpufreq_task_stats_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 #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: default avatarSiqi Lin <siqilin@google.com>
parent 60232518
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;