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

Skip to content
Commit 496e7559 authored by Sultan Alsawaf's avatar Sultan Alsawaf Committed by Alexander Alexeev
Browse files

kernel: Fix massive cpufreq stats memory leaks



Every time _cpu_up() is called for a CPU, idle_thread_get() is called which
then re-initializes a CPU's idle thread that was already previously created
and cached in a global variable in smpboot.c. idle_thread_get() calls
init_idle() which then calls __sched_fork(). __sched_fork() is where
cpufreq_task_stats_init() is, and cpufreq_task_stats_init() allocates
512 bytes of memory to a pointer in the task struct.

Since idle_thread_get() reuses a task struct instance that was already
previously created, this means that every time it calls init_idle(),
cpufreq_task_stats_init() allocates 512 bytes again and overwrites the
existing 512-byte allocation that the idle thread already had.

This causes 512 bytes to be leaked every time a CPU is onlined. This is
significant when non-boot CPUs are enabled during resume from suspend; this
means that (NR_CPUS - 1) * 512 bytes are leaked every time the device exits
suspend (this turned out to be ~500 kiB leaked in 20 minutes with the
device left on a desk with the screen off).

In order to fix this, don't initialize cpufreq stats at all for the idle
threads. The cpufreq stats interface is intended to be used for tracking
userspace tasks, so we can safely remove it from the kernel's idle threads
without killing any functionality.

But that's not all!

Task structs can be freed outside of release_task(), which creates another
memory leak because a task struct can be freed without having its cpufreq
stats allocation freed. To fix this, free the cpufreq stats allocation at
the same time that task struct allocations are freed.

Change-Id: Ifecf515d8b6f3c517e04c02ba5e06f24814e938e
Signed-off-by: default avatarSultan Alsawaf <sultanxda@gmail.com>
parent 57b19b76
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment