[RFC PATCH 00/15] arm64: Set kernel stack size from cmdline
From: Mostafa Saleh
Date: Mon Sep 28 2026 - 13:51:49 EST
Summary
=======
This patch series adds the ability to configure the kernel stack size
for arm64 from the kernel command line.
On some systems (specifically, Android), this provides a mechanism to
reduce the kernel memory consumption, as the default kernel stack size
of 16kB (with 4kB pages) can result in ~100MB of allocated memory,
despite the fact that most threads do not come close to exhausting
their allocation [1].
There have been multiple alternative attempts to improve this
situation, including for x86 and cloud workloads. However, these
have typically focussed on more dynamic behaviours such as allocating
kernel stack pages lazily (based on faults) [2] or reclaiming unused
stack pages from blocked tasks [1], whereas this series focusses on
making the kernel stack size configurable without changing the way in
which it is allocated.
It also permits a 12kB stack size, which is currently not supported
by arm64's stack overflow checking logic.
This series re-uses the first part of the dynamic stack patches which
makes it possible to partially back the VA space of the stack
(THREAD_SIZE) with memory, but never attempts to dynamically grow the
stack.
The size of the stack (<= THREAD_SIZE) is determined from the kernel
command line and is not further configurable at runtime, all threads
on the system (except the init_task, see below) will use the size set
from the command line.
Patches
=======
The patches have dependency on the ongoing arm re-work[3] to move the
overflow stack to sp_el1 allowing the early kernel exception to use it
without clobbering any registers.
- Patches 01-09: have no functional change, they abstract the code
dealing with the stack to avoid hardcoding the stack size
- Patches 10-13: Introduce the new ARCH_HAS_VARIABLE_STACK_SIZE and
make the kernel deal with stack sizes set in the run time.
- Patches 14-15: arm64 selecting ARCH_HAS_VARIABLE_STACK_SIZE and
setting the kernel stack size from the command line.
KASAN
======
The KASAN stack helpers keep unpoisoning the whole THREAD_SIZE area.
As they only write shadow memory which is populated for the whole vmap
area.
init_task
=========
init_task is the only kernel thread that has a full stack allocation
as it is allocated statically. However, the additional stack pages are
not usable because the overflow check on exception entry will continue
to check against the configured stack size.
Future work
===========
There are multiple paths that can build on this
- Per task stack size (either via an in-kernel API for kthreads or
potentially a prctl() for userspace to configure)
- It is still possible to build on top of this on the fault path to
add dynamic stacks if the challenges raised in [2] can be solved.
Will Deacon will host a discussion at LPC next week [4]
Testing
=======
I tested on Lenovo Mini-x gen 10 (Qualcomm X1 CPU).
With configs KMEMLEAK, DEBUG_STACK_USAGE, SCHED_STACK_END_CHECK.
1) 4kB kernel - 16kB stack (default)
2) 4kB kernel - 8kB stack
3) 4kB kernel - 12kB stack
4) 64kB kernel - 64kB stack
With running VMs with KVM, stress-ng and LKDTM.
16kB tests done on Qemu.
[1] https://lore.kernel.org/all/20260827232948.2520558-1-stevensd@xxxxxxxxxx/
[2] https://lore.kernel.org/all/20260424191456.2679717-1-stevensd@xxxxxxxxxx/
[3] https://lore.kernel.org/all/20260918161407.2300-1-will@xxxxxxxxxx/
[4] https://lpc.events/event/20/contributions/2419/
David Stevens (3):
fork: Don't assume fully populated stack during reuse
fork: Move vm_stack to the beginning of the stack
fork: Move vmap stack freeing to work queue
Mostafa Saleh (9):
sched/task_stack: Add helpers for stack high/low
exit: Don't assume the kernel stack size
usercopy: Don't assume the kernel stack size
mm: kmemleak: Don't assume the kernel stack size
arm64: Don't assume the kernel stack size
sched/task_stack: Introduce ARCH_HAS_VARIABLE_STACK_SIZE
fork: Implement partial VMAP stack allocation
arm64: mm: Relax kernel stack alignment
arm64: mm: Set stack size from the kernel command line
Pasha Tatashin (3):
fork: Remove assumption that vm_area->nr_pages equals to THREAD_SIZE
fork: Separate vmap stack allocation and free calls
mm/vmalloc: Add a get_vm_area_node()
.../admin-guide/kernel-parameters.txt | 7 +
arch/Kconfig | 10 ++
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/memory.h | 19 ++-
arch/arm64/include/asm/stacktrace.h | 4 +-
arch/arm64/kernel/entry.S | 91 ++++++++++--
arch/arm64/kernel/setup.c | 24 ++++
arch/arm64/kernel/traps.c | 5 +-
include/linux/sched/task_stack.h | 61 +++++++-
include/linux/thread_info.h | 8 ++
include/linux/vmalloc.h | 3 +
kernel/exit.c | 2 +-
kernel/fork.c | 134 +++++++++++++++---
mm/kmemleak.c | 2 +-
mm/usercopy.c | 4 +-
mm/vmalloc.c | 24 ++++
16 files changed, 348 insertions(+), 51 deletions(-)
--
2.56.0.rc1.315.gc6ed9934b7-goog