Re: [RFC 06/10] Reclaim memory from blocked kernel stacks
From: David Stevens
Date: Fri Aug 28 2026 - 17:18:15 EST
On Fri, Aug 28, 2026 at 6:36 AM Sebastian Andrzej Siewior
<bigeasy@xxxxxxxxxxxxx> wrote:
>
> On 2026-08-27 16:29:44 [-0700], David Stevens wrote:
> > diff --git a/arch/Kconfig b/arch/Kconfig
> > index fa7507ac8e13..adb4a5957996 100644
> > --- a/arch/Kconfig
> > +++ b/arch/Kconfig
> > @@ -1534,6 +1534,24 @@ config VMAP_STACK
> > backing virtual mappings with real shadow memory, and KASAN_VMALLOC
> > must be enabled.
> >
> > +config HAVE_ARCH_RECLAIMABLE_STACK
> > + def_bool n
> > +
> > +config RECLAIMABLE_STACK
> > + default !PREEMPT_RT && !PROC_KCORE
>
> This shouldn't default like this for RT. It either is useable or it is
> not.
>
> > + bool "Allow stacks of some blocked threads to be reclaimed"
> > + depends on VMAP_STACK && !STACK_GROWSUP
> > + depends on HAVE_ARCH_RECLAIMABLE_STACK
> > + depends on !DEBUG_STACK_USAGE
> > + depends on !KASAN_VMALLOC # TODO: add support for this
> > + depends on !DEBUG_KMEMLEAK # TODO: add support for this
> > + help
> > + Enable this to allow the unused portion of kernel stacks of most
> > + blocked tasks to be reclaimed.
> > +
> > + The wakeup latency of tasks with reclaimed stacks may increase,
> > + especially while the system is under memory pressure.
>
> It says *may* increase and on RT it _definitely_ will increase since
> there is a kworker involved not to mention the memory allocation itself.
You're correct that this phrasing is wrong. A more accurate way to say
it might be: "Under memory pressure, tasks that are not scheduled for
extended periods may have their stacks reclaimed. Such tasks will
experience increased wakeup latency."
> Anyway. This either needs to stay away from PREEMPT_RT or find a way to
> exclude at the very least mlock()ed tasks.
Disabling kernel stack reclaim for mlockall() tasks definitely makes sense.
> Did lockdep see this?
What are you referring to by "this"? I did stress testing with lockdep
enabled and didn't see any errors, although I will admit the bulk of
that stress testing was !PREEMPT_RT.
> If I understood the whole exercise correct then you have a kernel stack
> of two pages and in best case you can unmap and release the second page
> while the task is napping.
>
> What might be a tad simpler is to memset(,0,) the remaining part of the
> stack. Since the stack is vmap-ed it should be swapped out on its own
> without additional tricks. That memset() would help zram to compress
> better so it uses less memory. ta-da.
>
> What also should be simpler (and I am not saying just to move you away
> from the scheduler) is to have a shrinker which iterates over all tasks
> which are marked for reclaim and then similar to swap just unmap both
> stack pages and release the second page which is not used.
> Upon wake up the task should create a page_fault which would be used to
> allocate the second stack page and map the whole stack again.
>
> This sounds simpler.
There is no swap for kernel memory, only user memory. I did contribute
to some previous work that aimed to only only prepopulate one page of
each kernel stack and then to dynamically fault in further pages as
needed [1], but handling that architecturally and guaranteeing that
memory is available when needed is difficult. Full-on swap to zram
within the kernel would complicate pre-allocating pages for kernel
stack faults further, since you could start getting inter-thread
kernel stack faults due to blocked tasks putting pointers to their
stacks into waitqueues and similar structures.
[1] https://lore.kernel.org/linux-mm/20260424191456.2679717-1-stevensd@xxxxxxxxxx/#r